Allow showing player ranking in network user dialog

This commit is contained in:
Benau 2018-06-03 15:08:52 +08:00
parent 7e5263168e
commit e122d045cc
6 changed files with 201 additions and 98 deletions

View File

@ -43,9 +43,23 @@ void NetworkUserDialog::beforeAddingWidgets()
assert(m_name_widget != NULL);
m_name_widget->setText(m_name, false);
m_info_widget = getWidget<LabelWidget>("info");
assert(m_info_widget != NULL);
if (m_online_id != 0)
{
updatePlayerRanking(m_name, m_online_id, m_info_widget,
m_fetched_ranking);
}
else
{
m_info_widget->setVisible(false);
}
m_friend_widget = getWidget<IconButtonWidget>("friend");
assert(m_friend_widget != NULL);
m_friend_widget->setVisible(m_online_id != 0);
m_friend_widget->setVisible(m_online_id != 0 &&
PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_SIGNED_IN
&& m_online_id != PlayerManager::getCurrentPlayer()->getOnlineId());
// Hide friend request button if already friend
Online::OnlineProfile* opp =
@ -66,7 +80,8 @@ void NetworkUserDialog::beforeAddingWidgets()
//I18N: In the network user dialog
m_kick_widget->setText(_("Kick"));
m_kick_widget->setVisible(STKHost::get()->isAuthorisedToControl());
m_kick_widget->setVisible(STKHost::get()->isAuthorisedToControl()
&& m_host_id != STKHost::get()->getMyHostId());
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
assert(m_cancel_widget != NULL);
@ -79,9 +94,29 @@ void NetworkUserDialog::beforeAddingWidgets()
getWidget<IconButtonWidget>("accept")->setVisible(false);
getWidget<IconButtonWidget>("remove")->setVisible(false);
getWidget<IconButtonWidget>("enter")->setVisible(false);
getWidget<LabelWidget>("info")->setVisible(false);
} // beforeAddingWidgets
// -----------------------------------------------------------------------------
void NetworkUserDialog::onUpdate(float dt)
{
if (*m_fetched_ranking == false)
{
// I18N: In the network player dialog, showing when waiting for
// the result of the ranking info of a player
core::stringw fetching =
StringUtils::loadingDots(_("Fetching ranking info for %s.",
m_name));
m_info_widget->setText(fetching, false);
}
// It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy)
{
ModalDialog::dismiss();
return;
}
} // onUpdate
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation
NetworkUserDialog::processEvent(const std::string& source)

View File

@ -20,9 +20,11 @@
#define HEADER_NETWORK_USER_DIALOG_HPP
#include "guiengine/modaldialog.hpp"
#include "states_screens/dialogs/ranking_callback.hpp"
#include "utils/types.hpp"
#include <irrString.h>
#include <memory>
namespace GUIEngine
{
@ -35,7 +37,8 @@ namespace GUIEngine
* \brief Dialog that handle user in network lobby
* \ingroup states_screens
*/
class NetworkUserDialog : public GUIEngine::ModalDialog
class NetworkUserDialog : public GUIEngine::ModalDialog,
public RankingCallback
{
private:
const uint32_t m_host_id;
@ -46,21 +49,26 @@ private:
bool m_self_destroy;
GUIEngine::RibbonWidget * m_options_widget;
std::shared_ptr<bool> m_fetched_ranking;
GUIEngine::LabelWidget * m_name_widget;
GUIEngine::RibbonWidget* m_options_widget;
GUIEngine::IconButtonWidget * m_friend_widget;
GUIEngine::LabelWidget* m_name_widget;
GUIEngine::IconButtonWidget * m_kick_widget;
GUIEngine::LabelWidget* m_info_widget;
GUIEngine::IconButtonWidget * m_cancel_widget;
GUIEngine::IconButtonWidget* m_friend_widget;
GUIEngine::IconButtonWidget* m_kick_widget;
GUIEngine::IconButtonWidget* m_cancel_widget;
public:
NetworkUserDialog(uint32_t host_id, uint32_t online_id,
const core::stringw& name)
: ModalDialog(0.8f,0.8f), m_host_id(host_id), m_online_id(online_id),
m_name(name), m_self_destroy(false)
m_name(name), m_self_destroy(false),
m_fetched_ranking(std::make_shared<bool>(false))
{
loadFromFile("online/user_info_dialog.stkgui");
}
@ -75,15 +83,8 @@ public:
// ------------------------------------------------------------------------
virtual bool onEscapePressed();
// ------------------------------------------------------------------------
virtual void onUpdate(float dt)
{
// It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy)
{
ModalDialog::dismiss();
return;
}
}
virtual void onUpdate(float dt);
};
#endif

View File

@ -42,16 +42,17 @@ std::vector<std::tuple<int, core::stringw, float> >
PlayerRankingsDialog::PlayerRankingsDialog(uint32_t online_id,
const core::stringw& name)
: ModalDialog(0.8f,0.9f), m_online_id(online_id),
m_name(name), m_self_destroy(false)
m_name(name), m_self_destroy(false),
m_fetched_ranking(std::make_shared<bool>(false))
{
loadFromFile("online/player_rankings_dialog.stkgui");
m_top_ten = getWidget<ListWidget>("top-ten");
assert(m_top_ten != NULL);
if (m_rankings.empty())
updateTopTen();
updateTopTenList();
else
addTopTen();
fillTopTenList();
} // PlayerRankingsDialog
// -----------------------------------------------------------------------------
@ -67,66 +68,18 @@ void PlayerRankingsDialog::beforeAddingWidgets()
m_ranking_info = getWidget<LabelWidget>("cur-rank");
assert(m_ranking_info != NULL);
core::stringw fetching = _("Fetching ranking info for %s.", m_name);
m_ranking_info->setText(fetching, false);
updatePlayerRanking();
updatePlayerRanking(m_name, m_online_id, m_ranking_info,
m_fetched_ranking);
} // beforeAddingWidgets
// -----------------------------------------------------------------------------
void PlayerRankingsDialog::updatePlayerRanking()
{
class UpdatePlayerRankingRequest : public XMLRequest
{
// ------------------------------------------------------------------------
/** Callback for the request to send a friend invitation. Shows a
* confirmation message and takes care of updating all the cached
* information.
*/
virtual void callback()
{
PlayerRankingsDialog* prd = dynamic_cast<PlayerRankingsDialog*>
(getCurrent());
if (prd == NULL)
return;
core::stringw result = _("%s has no ranking yet.", prd->m_name);
if (isSuccess())
{
int rank = -1;
float score = 0.0;
getXMLData()->get("rank", &rank);
getXMLData()->get("scores", &score);
if (rank > 0)
{
result = _("%s has a rank of %d with score %d.",
prd->m_name, rank, (int)score);
}
}
prd->m_ranking_info->setText(result, false);
} // callback
public:
UpdatePlayerRankingRequest() : XMLRequest(true) {}
}; // UpdatePlayerRankingRequest
// ------------------------------------------------------------------------
UpdatePlayerRankingRequest* request = new UpdatePlayerRankingRequest();
PlayerManager::setUserDetails(request, "get-ranking");
request->addParameter("id", m_online_id);
request->queue();
} // updatePlayerRanking
// ----------------------------------------------------------------------------
void PlayerRankingsDialog::updateTopTen()
void PlayerRankingsDialog::updateTopTenList()
{
// ----------------------------------------------------------------
// ------------------------------------------------------------------------
class UpdateTopTenRequest : public XMLRequest
{
/** Callback for the request to accept a friend invitation. Shows a
* confirmation message and takes care of updating all the cached
* information.
/** Callback for the request to update top 10 players and update the
* list.
*/
virtual void callback()
{
@ -148,7 +101,7 @@ void PlayerRankingsDialog::updateTopTen()
players->getNode(i)->get("scores", &score);
prd->m_rankings.emplace_back(rank, user, score);
}
prd->addTopTen();
prd->fillTopTenList();
}
} // callback
public:
@ -160,10 +113,10 @@ void PlayerRankingsDialog::updateTopTen()
PlayerManager::setUserDetails(request, "top-players");
request->addParameter("ntop", 10);
request->queue();
} // updateTopTen
} // updateTopTenList
// -----------------------------------------------------------------------------
void PlayerRankingsDialog::addTopTen()
void PlayerRankingsDialog::fillTopTenList()
{
m_top_ten->clear();
for (auto& r : m_rankings)
@ -177,7 +130,28 @@ void PlayerRankingsDialog::addTopTen()
StringUtils::toWString(std::get<2>(r)), -1, 1, true));
m_top_ten->addItem("rank", row);
}
} // addTopTen
} // fillTopTenList
// -----------------------------------------------------------------------------
void PlayerRankingsDialog::onUpdate(float dt)
{
if (*m_fetched_ranking == false)
{
// I18N: In the network player dialog, showing when waiting for
// the result of the ranking info of a player
core::stringw fetching =
StringUtils::loadingDots(_("Fetching ranking info for %s.",
m_name));
m_ranking_info->setText(fetching, false);
}
// It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy)
{
ModalDialog::dismiss();
return;
}
} // onUpdate
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation
@ -201,8 +175,10 @@ GUIEngine::EventPropagation
return GUIEngine::EVENT_BLOCK;
timer = StkTime::getRealTime();
updatePlayerRanking();
updateTopTen();
*m_fetched_ranking = false;
updatePlayerRanking(m_name, m_online_id, m_ranking_info,
m_fetched_ranking);
updateTopTenList();
return GUIEngine::EVENT_BLOCK;
}
}

View File

@ -20,9 +20,11 @@
#define HEADER_PLAYER_RANKINGS_DIALOG_HPP
#include "guiengine/modaldialog.hpp"
#include "states_screens/dialogs/ranking_callback.hpp"
#include "utils/types.hpp"
#include <irrString.h>
#include <memory>
#include <tuple>
#include <vector>
@ -38,7 +40,8 @@ namespace GUIEngine
* \brief Dialog that handle user in network lobby
* \ingroup states_screens
*/
class PlayerRankingsDialog : public GUIEngine::ModalDialog
class PlayerRankingsDialog : public GUIEngine::ModalDialog,
public RankingCallback
{
private:
const uint32_t m_online_id;
@ -47,6 +50,8 @@ private:
bool m_self_destroy;
std::shared_ptr<bool> m_fetched_ranking;
GUIEngine::RibbonWidget* m_options_widget;
GUIEngine::LabelWidget* m_ranking_info;
@ -61,11 +66,9 @@ private:
/*scores*/float> > m_rankings;
// ------------------------------------------------------------------------
void updatePlayerRanking();
void updateTopTenList();
// ------------------------------------------------------------------------
void updateTopTen();
// ------------------------------------------------------------------------
void addTopTen();
void fillTopTenList();
public:
PlayerRankingsDialog(uint32_t online_id, const core::stringw& name);
@ -84,15 +87,7 @@ public:
return false;
}
// ------------------------------------------------------------------------
virtual void onUpdate(float dt)
{
// It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy)
{
ModalDialog::dismiss();
return;
}
}
virtual void onUpdate(float dt);
};
#endif

View File

@ -0,0 +1,97 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2018 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_RANKING_CALLBACK_HPP
#define HEADER_RANKING_CALLBACK_HPP
#include "config/player_manager.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "online/xml_request.hpp"
#include <memory>
class RankingCallback
{
protected:
// ------------------------------------------------------------------------
void updatePlayerRanking(const core::stringw& name, uint32_t online_id,
GUIEngine::LabelWidget* info,
std::shared_ptr<bool> done)
{
// --------------------------------------------------------------------
class UpdatePlayerRankingRequest : public Online::XMLRequest
{
private:
std::weak_ptr<bool> m_done;
core::stringw m_name;
GUIEngine::LabelWidget* m_info;
// ----------------------------------------------------------------
/** Callback for the request to update rank of a player. Shows his
* rank and score.
*/
virtual void callback()
{
auto done = m_done.lock();
// Dialog deleted
if (!done)
return;
// I18N: In the network player dialog, indiciating a network
// player has no ranking
core::stringw result = _("%s has no ranking yet.", m_name);
if (isSuccess())
{
int rank = -1;
float score = 0.0;
getXMLData()->get("rank", &rank);
getXMLData()->get("scores", &score);
if (rank > 0)
{
// I18N: In the network player dialog show rank and
// score of a player
result = _("%s has a rank of %d with score %d.",
m_name, rank, (int)score);
}
}
*done = true;
m_info->setText(result, false);
} // callback
public:
UpdatePlayerRankingRequest(const core::stringw& name,
uint32_t online_id,
GUIEngine::LabelWidget* info,
std::shared_ptr<bool> done)
: XMLRequest(true)
{
m_name = name;
m_info = info;
m_done = done;
}
}; // UpdatePlayerRankingRequest
// --------------------------------------------------------------------
UpdatePlayerRankingRequest* request =
new UpdatePlayerRankingRequest(name, online_id, info, done);
PlayerManager::setUserDetails(request, "get-ranking");
request->addParameter("id", online_id);
request->queue();
}
};
#endif

View File

@ -302,8 +302,7 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name,
{
auto host_online_ids = StringUtils::splitToUInt
(m_player_list->getSelectionInternalName(), '_');
if (host_online_ids.size() != 2 ||
STKHost::get()->getMyHostId() == host_online_ids[0])
if (host_online_ids.size() != 2)
{
return;
}