Implement server bookmarks for global networking

This commit is contained in:
Benau 2021-07-12 16:50:16 +08:00
parent 6f7a196c70
commit b465729304
9 changed files with 146 additions and 4 deletions

View File

@ -29,6 +29,8 @@
<buttonbar id="options" width="90%" proportion="4" align="center">
<icon-button id="join" width="128" height="128" icon="gui/icons/green_check.png"
I18N="In the server info dialog" text="Join" label_location="bottom"/>
<icon-button id="bookmark" width="128" height="128" icon="gui/icons/story_mode_book.png"
I18N="In the server info dialog" text="Bookmark this server" label_location="bottom"/>
<icon-button id="cancel" width="128" height="128" icon="gui/icons/main_quit.png"
I18N="In the server info dialog" text="Cancel" label_location="bottom"/>
</buttonbar>

View File

@ -3,11 +3,12 @@
<div x="1%" y="0" width="98%" layout="horizontal-row" height="9%">
<icon-button id="back" height="100%" icon_align="left" icon="gui/icons/back.png"/>
<spacer proportion="1" height="1"/>
<icon-button id="bookmark" y="5%" height="90%" icon_align="right" icon="gui/icons/story_mode_book.png"/>
<icon-button id="reload" y="5%" height="90%" icon_align="right" icon="gui/icons/restart.png"/>
</div>
<div x="0%" y="1%" width="100%" height="98%" layout="vertical-row" >
<header width="80%" height="8%" align="center" text_align="center" text="Server Selection"/>
<header id="title_header" width="80%" height="8%" align="center" text_align="center" text="Server Selection"/>
<spacer width="100%" height="1%"/>
<box proportion="1" width="98%" align="center" layout="vertical-row" padding="6">

View File

@ -803,6 +803,11 @@ namespace UserConfigParams
PARAM_PREFIX bool m_profiler_enabled PARAM_DEFAULT( false );
// ---- Networking
PARAM_PREFIX StringToUIntUserConfigParam m_server_bookmarks
PARAM_DEFAULT(StringToUIntUserConfigParam("server-bookmarks",
"Wan server bookmarks",
{{ "server-bookmarks", "server-name", "owner" }}, {}));
PARAM_PREFIX StringToUIntUserConfigParam m_address_history
PARAM_DEFAULT(StringToUIntUserConfigParam("address-history",
"Last 5 IP addresses that user entered",

View File

@ -240,6 +240,13 @@ void Server::setAddress(const SocketAddress& addr)
m_address.reset(new SocketAddress(addr));
} // setAddress
// ----------------------------------------------------------------------------
std::string Server::getBookmarkKey() const
{
return StringUtils::xmlEncode(m_name) +
StringUtils::toString(m_server_owner);
} // getBookmarkKey
// ----------------------------------------------------------------------------
void UserDefinedServer::saveServer() const
{

View File

@ -208,6 +208,8 @@ public:
// ------------------------------------------------------------------------
void setReconnectWhenQuitLobby(bool val)
{ m_reconnect_when_quit_lobby = val; }
// ------------------------------------------------------------------------
std::string getBookmarkKey() const;
}; // Server
class UserDefinedServer : public Server

View File

@ -17,6 +17,8 @@
#include "states_screens/dialogs/server_info_dialog.hpp"
#include "io/file_manager.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/widgets/icon_button_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
@ -27,6 +29,7 @@
#include "network/server_config.hpp"
#include "network/stk_host.hpp"
#include "states_screens/online/networking_lobby.hpp"
#include "states_screens/online/server_selection.hpp"
#include "states_screens/state_manager.hpp"
#include "tracks/track.hpp"
#include "utils/string_utils.hpp"
@ -54,6 +57,11 @@ ServerInfoDialog::ServerInfoDialog(std::shared_ptr<Server> server)
m_self_destroy = false;
m_join_server = false;
m_bookmark_icon = irr_driver->getTexture
(file_manager->getAsset(FileManager::GUI_ICON, "story_mode_book.png"));
m_remove_icon = irr_driver->getTexture
(file_manager->getAsset(FileManager::GUI_ICON, "remove.png"));
loadFromFile("online/server_info_dialog.stkgui");
getWidget<LabelWidget>("title")->setText(server->getName(), true);
@ -145,6 +153,8 @@ ServerInfoDialog::ServerInfoDialog(std::shared_ptr<Server> server)
{
getWidget("player-list")->setVisible(false);
}
if (m_server->getServerOwner() != 0)
updateBookmarkStatus(false);
} // ServerInfoDialog
// -----------------------------------------------------------------------------
@ -186,11 +196,16 @@ GUIEngine::EventPropagation
m_self_destroy = true;
return GUIEngine::EVENT_BLOCK;
}
else if(selection == m_join_widget->m_properties[PROP_ID])
else if (selection == m_join_widget->m_properties[PROP_ID])
{
m_join_server = true;
return GUIEngine::EVENT_BLOCK;
}
else if (selection == m_bookmark_widget->m_properties[PROP_ID])
{
updateBookmarkStatus(true);
return GUIEngine::EVENT_BLOCK;
}
}
return GUIEngine::EVENT_LET;
} // processEvent
@ -234,3 +249,45 @@ void ServerInfoDialog::onUpdate(float dt)
if (m_join_server)
requestJoin();
} // onUpdate
// -----------------------------------------------------------------------------
void ServerInfoDialog::updateBookmarkStatus(bool change_bookmark)
{
const std::string& key = m_server->getBookmarkKey();
std::map<std::string, uint32_t>& bookmarks =
UserConfigParams::m_server_bookmarks;
auto it = bookmarks.find(key);
if (it == bookmarks.end())
{
if (change_bookmark)
{
bookmarks[key] = m_server->getServerOwner();
m_bookmark_widget->setLabel(_("Remove from bookmarks"));
m_bookmark_widget->setImage(m_remove_icon);
}
}
else
{
if (change_bookmark)
{
bookmarks.erase(key);
m_bookmark_widget->setLabel(_("Bookmark this server"));
m_bookmark_widget->setImage(m_bookmark_icon);
}
else
{
m_bookmark_widget->setLabel(_("Remove from bookmarks"));
m_bookmark_widget->setImage(m_remove_icon);
}
}
ServerSelection::getInstance()->copyFromServerList();
} // updateBookmarkStatus
// -----------------------------------------------------------------------------
void ServerInfoDialog::beforeAddingWidgets()
{
m_bookmark_widget = getWidget<IconButtonWidget>("bookmark");
assert(m_bookmark_widget != NULL);
if (m_server->getServerOwner() == 0)
m_bookmark_widget->setVisible(false);
}

View File

@ -54,15 +54,23 @@ private:
/** The cancel button. */
GUIEngine::IconButtonWidget *m_cancel_widget;
GUIEngine::IconButtonWidget *m_bookmark_widget;
/** Specify server password if needed. */
GUIEngine::TextBoxWidget* m_password;
video::ITexture* m_bookmark_icon;
video::ITexture* m_remove_icon;
void updateBookmarkStatus(bool change_bookmark);
public:
ServerInfoDialog(std::shared_ptr<Server> server);
~ServerInfoDialog();
void onEnterPressedInternal();
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
virtual void beforeAddingWidgets();
virtual bool onEscapePressed();
virtual void onUpdate(float dt);

View File

@ -42,7 +42,7 @@
#include <cassert>
using namespace Online;
bool g_bookmarks_next = false;
// ----------------------------------------------------------------------------
/** Constructor, which loads the stkgui file.
*/
@ -112,6 +112,12 @@ void ServerSelection::loadedFromFile()
assert(m_searcher != NULL);
m_ipv6->setState(false);
m_icon_bank = new irr::gui::STKModifiedSpriteBank(GUIEngine::getGUIEnv());
m_bookmark_widget = getWidget<GUIEngine::IconButtonWidget>("bookmark");
assert(m_bookmark_widget != NULL);
m_bookmark_icon = irr_driver->getTexture
(file_manager->getAsset(FileManager::GUI_ICON, "story_mode_book.png"));
m_global_icon = irr_driver->getTexture
(file_manager->getAsset(FileManager::GUI_ICON, "main_network.png"));
} // loadedFromFile
// ----------------------------------------------------------------------------
@ -141,7 +147,9 @@ void ServerSelection::beforeAddingWidget()
void ServerSelection::init()
{
Screen::init();
m_last_load_time = -5000;
updateHeader();
#ifndef ENABLE_IPV6
m_ipv6->setState(false);
@ -207,6 +215,7 @@ void ServerSelection::init()
void ServerSelection::loadList()
{
m_server_list_widget->clear();
std::stable_sort(m_servers.begin(), m_servers.end(), [this]
(const std::shared_ptr<Server> a,
const std::shared_ptr<Server> b)->bool
@ -323,6 +332,12 @@ void ServerSelection::eventCallback(GUIEngine::Widget* widget,
{
refresh();
}
else if (name == "bookmark")
{
g_bookmarks_next = !g_bookmarks_next;
updateHeader();
copyFromServerList();
}
else if (name == "private_server" || name == "ipv6")
{
if (!m_ip_warning_shown && m_ipv6->getState() &&
@ -401,6 +416,24 @@ void ServerSelection::onUpdate(float dt)
m_refreshing_server = false;
if (!m_server_list->m_servers.empty())
{
std::set<std::string> all_possible_keys;
if (NetworkConfig::get()->isWAN())
{
// Remove offline server from bookmarks
for (auto& server : m_server_list->m_servers)
all_possible_keys.insert(server->getBookmarkKey());
std::map<std::string, uint32_t>& bookmarks =
UserConfigParams::m_server_bookmarks;
auto it = bookmarks.begin();
while (it != bookmarks.end())
{
if (all_possible_keys.find(it->first) ==
all_possible_keys.end())
it = bookmarks.erase(it);
else
it++;
}
}
int selection = m_server_list_widget->getSelectionID();
std::string selection_str = m_server_list_widget
->getSelectionInternalName();
@ -460,6 +493,18 @@ void ServerSelection::copyFromServerList()
return false;
}), m_servers.end());
}
if (g_bookmarks_next)
{
m_servers.erase(std::remove_if(m_servers.begin(), m_servers.end(),
[](const std::shared_ptr<Server>& a)->bool
{
const std::string& key = a->getBookmarkKey();
auto it = UserConfigParams::m_server_bookmarks.find(key);
if (it == UserConfigParams::m_server_bookmarks.end())
return true;
return false;
}), m_servers.end());
}
loadList();
} // copyFromServerList
@ -469,3 +514,14 @@ void ServerSelection::unloaded()
delete m_icon_bank;
m_icon_bank = NULL;
} // unloaded
// ----------------------------------------------------------------------------
void ServerSelection::updateHeader()
{
m_bookmark_widget->setImage(g_bookmarks_next ?
m_global_icon : m_bookmark_icon);
if (g_bookmarks_next)
getWidget("title_header")->setText(_("Server Bookmarks"));
else
getWidget("title_header")->setText(_("Server Selection"));
} // updateHeader

View File

@ -64,6 +64,9 @@ private:
GUIEngine::CheckBoxWidget* m_private_server;
GUIEngine::CheckBoxWidget* m_ipv6;
GUIEngine::IconButtonWidget* m_reload_widget;
GUIEngine::IconButtonWidget* m_bookmark_widget;
video::ITexture* m_bookmark_icon;
video::ITexture* m_global_icon;
GUIEngine::LabelWidget* m_update_status;
GUIEngine::ListWidget* m_server_list_widget;
GUIEngine::TextBoxWidget* m_searcher;
@ -81,7 +84,7 @@ private:
/** Load the servers into the main list.*/
void loadList();
void copyFromServerList();
void updateHeader();
void refresh();
@ -118,6 +121,7 @@ public:
virtual bool onEnterPressed(const irr::core::stringw& text) OVERRIDE
{ return false; }
void copyFromServerList();
}; // ServerSelection
#endif