Added last entered IP addresses list (#4525)

This commit is contained in:
Kuba 2021-05-06 19:01:24 +02:00 committed by GitHub
parent 1e38cba76c
commit 8add6fba2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 264 additions and 38 deletions

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="2%" y="2%" width="96%" height="50%" layout="vertical-row">
<label id="title" raw_text="Text" width="100%" height="36%"/>
<list id="list_history" x="0" y="37%" width="96%" height="63%" word_wrap="true" />
</div>
<div x="2%" y="70%" width="96%" height="30%" layout="vertical-row" >
<spacer height="7%" width="10" />
<textbox id="textfield" width="75%" align="center" />
<spacer height="9%" width="10" />
<buttonbar id="buttons" height="50%" width="54%" align="center">
<icon-button id="ok" width="128" height="128" icon="gui/icons/green_check.png"
I18N="In the enter address dialog" text="OK" align="center"/>
<icon-button id="cancel" width="128" height="128" icon="gui/icons/remove.png"
I18N="In the enter address dialog" text="Cancel" align="center"/>
</buttonbar>
<spacer height="1f" width="20" />
</div>
</stkgui>

View File

@ -1,5 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically.
# This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")

View File

@ -140,7 +140,7 @@ public:
irr::core::stringc toString() const;
operator std::map<T, U>&() const
operator std::map<T, U>&()
{
return m_elements;
}
@ -803,6 +803,11 @@ namespace UserConfigParams
PARAM_PREFIX bool m_profiler_enabled PARAM_DEFAULT( false );
// ---- Networking
PARAM_PREFIX StringToUIntUserConfigParam m_address_history
PARAM_DEFAULT(StringToUIntUserConfigParam("address-history",
"Last 5 IP addresses that user entered",
{{ "server-address", "address", "last-connection" }}, {}));
// These stk domains have only a record to each ipv6 stun below,
// so we can use this to know ipv4 address of nat64 gateway (if any)
PARAM_PREFIX StringToUIntUserConfigParam m_stun_servers_v4

View File

@ -0,0 +1,168 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2015 Marianne Gagnon
//
// 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.
#include "states_screens/dialogs/enter_address_dialog.hpp"
#include "config/user_config.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
#include "network/server.hpp"
#include "network/socket_address.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include <vector>
#include <utility>
#include <IGUIEnvironment.h>
// ------------------------------------------------------------------------
EnterAddressDialog::EnterAddressDialog(std::shared_ptr<Server>* entered_server)
: ModalDialog(0.95f, 0.8f, GUIEngine::MODAL_DIALOG_LOCATION_BOTTOM),
m_self_destroy(false)
{
loadFromFile("enter_address_dialog.stkgui");
m_text_field = getWidget<GUIEngine::TextBoxWidget>("textfield");
m_title = getWidget<GUIEngine::LabelWidget>("title");
m_title->setText(_("Enter the server address optionally followed by : and"
" then port or select address from list."), false);
m_entered_server = entered_server;
m_list = getWidget<GUIEngine::ListWidget>("list_history");
loadList();
GUIEngine::RibbonWidget* buttons_ribbon =
getWidget<GUIEngine::RibbonWidget>("buttons");
buttons_ribbon->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
buttons_ribbon->select("cancel", PLAYER_ID_GAME_MASTER);
} // EnterAddressDialog
// ------------------------------------------------------------------------
EnterAddressDialog::~EnterAddressDialog()
{
m_text_field->getIrrlichtElement()->remove();
m_text_field->clearListeners();
} // ~EnterAddressDialog
// ------------------------------------------------------------------------
void EnterAddressDialog::onUpdate(float dt)
{
if (m_self_destroy)
{
GUIEngine::getGUIEnv()
->removeFocus(m_text_field->getIrrlichtElement());
GUIEngine::getGUIEnv()->removeFocus(m_irrlicht_window);
ModalDialog::dismiss();
}
} // onUpdate
// ------------------------------------------------------------------------
void EnterAddressDialog::onEnterPressedInternal()
{
if (!m_self_destroy && validate())
{
m_self_destroy = true;
UserConfigParams::m_address_history[
StringUtils::wideToUtf8(m_text_field->getText())] = (uint32_t)StkTime::getTimeSinceEpoch();
}
} // onEnterPressedInternal
// ------------------------------------------------------------------------
GUIEngine::EventPropagation EnterAddressDialog::processEvent(const std::string& event_source)
{
if (event_source == "buttons")
{
GUIEngine::RibbonWidget* buttons_ribbon =
getWidget<GUIEngine::RibbonWidget>("buttons");
const std::string& button =
buttons_ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (button == "cancel")
{
dismiss();
return GUIEngine::EVENT_BLOCK;
}
else if (button == "ok")
{
if (!m_self_destroy && validate())
{
m_self_destroy = true;
UserConfigParams::m_address_history[
StringUtils::wideToUtf8(m_text_field->getText())] = (uint32_t)StkTime::getTimeSinceEpoch();
}
return GUIEngine::EVENT_BLOCK;
}
}
if (event_source == "list_history")
{
m_text_field->setText(m_list->getSelectionLabel());
}
return GUIEngine::EVENT_LET;
} // processEvent
// ------------------------------------------------------------------------
bool EnterAddressDialog::validate()
{
core::stringw addr_w = m_text_field->getText();
std::string addr_u = StringUtils::wideToUtf8(addr_w);
SocketAddress server_addr(addr_u);
if (server_addr.getIP() == 0 && !server_addr.isIPv6())
{
core::stringw err = _("Invalid server address: %s.",
addr_w);
m_title->setText(err, true);
return false;
}
SocketAddress ipv4_addr = server_addr;
if (server_addr.isIPv6())
ipv4_addr.setIP(0);
auto server =
std::make_shared<UserDefinedServer>(addr_w, ipv4_addr);
if (server_addr.isIPv6())
{
server->setIPV6Address(server_addr);
server->setIPV6Connection(true);
}
*m_entered_server = server;
return true;
} // validate
// ------------------------------------------------------------------------
void EnterAddressDialog::loadList()
{
const unsigned MAX_ENTRIES = 5;
std::map<std::string, uint32_t>& addr = UserConfigParams::m_address_history;
std::vector<std::pair<std::string, uint32_t> > entries;
for (std::map<std::string,uint32_t>::iterator i = addr.begin();
i != addr.end(); i++)
entries.emplace_back(i->first, i->second);
std::sort(entries.begin(),entries.end(),
[](const std::pair<std::string,uint32_t>& a,
const std::pair<std::string,uint32_t>& b)->bool
{ return a.second > b.second; });
addr.clear();
for (unsigned i = 0; i < entries.size(); i++)
{
m_list->addItem("list_item",
std::vector<GUIEngine::ListWidget::ListCell>
{ GUIEngine::ListWidget::ListCell(StringUtils::utf8ToWide(entries[i].first)),
GUIEngine::ListWidget::ListCell(StringUtils::utf8ToWide(StkTime::toString(entries[i].second)))});
addr[entries[i].first] = entries[i].second;
if (i >= MAX_ENTRIES - 1)
break;
}
} // loadList

View File

@ -0,0 +1,64 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2015 Marianne Gagnon
//
// 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_ENTER_ADDRESS_DIALOG_HPP
#define HEADER_ENTER_ADDRESS_DIALOG_HPP
#include "guiengine/modaldialog.hpp"
#include "utils/cpp2011.hpp"
#include <memory>
class Server;
namespace GUIEngine
{
class LabelWidget;
class ListWidget;
class TextBoxWidget;
}
/**
* \brief Dialog that shows up when user wants to enter server address
* \ingroup states_screens
*/
class EnterAddressDialog : public GUIEngine::ModalDialog
{
private:
GUIEngine::LabelWidget* m_title;
GUIEngine::TextBoxWidget* m_text_field;
std::shared_ptr<Server>* m_entered_server;
bool m_self_destroy;
GUIEngine::ListWidget* m_list;
// ------------------------------------------------------------------------
void loadList();
// ------------------------------------------------------------------------
bool validate();
// ------------------------------------------------------------------------
public:
EnterAddressDialog(std::shared_ptr<Server>* entered_server);
// ------------------------------------------------------------------------
~EnterAddressDialog();
// ------------------------------------------------------------------------
virtual void onUpdate(float dt) OVERRIDE;
// ------------------------------------------------------------------------
virtual void onEnterPressedInternal() OVERRIDE;
// ------------------------------------------------------------------------
GUIEngine::EventPropagation processEvent(const std::string& event_source)
OVERRIDE;
// ------------------------------------------------------------------------
GUIEngine::TextBoxWidget* getTextField() const { return m_text_field; }
};
#endif

View File

@ -46,7 +46,7 @@
#include "states_screens/dialogs/message_dialog.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include "states_screens/dialogs/enter_address_dialog.hpp"
#include <string>
@ -235,41 +235,7 @@ void OnlineScreen::eventCallback(Widget* widget, const std::string& name,
MessageQueue::add(MessageQueue::MT_ERROR, msg);
return;
}
core::stringw instruction =
_("Enter the server address optionally followed by : and"
" then port.");
auto gtfd = new GeneralTextFieldDialog(instruction.c_str(),
[] (const irr::core::stringw& text) {},
[this] (GUIEngine::LabelWidget* lw,
GUIEngine::TextBoxWidget* tb)->bool
{
core::stringw addr_w = tb->getText();
std::string addr_u = StringUtils::wideToUtf8(addr_w);
SocketAddress server_addr(addr_u);
if (server_addr.getIP() == 0 && !server_addr.isIPv6())
{
core::stringw err = _("Invalid server address: %s.",
addr_w);
lw->setText(err, true);
return false;
}
SocketAddress ipv4_addr = server_addr;
if (server_addr.isIPv6())
ipv4_addr.setIP(0);
auto server =
std::make_shared<UserDefinedServer>(addr_w, ipv4_addr);
if (server_addr.isIPv6())
{
server->setIPV6Address(server_addr);
server->setIPV6Connection(true);
}
m_entered_server = server;
return true;
});
if (!m_entered_server_name.empty())
{
gtfd->getTextField()->setText(m_entered_server_name);
}
new EnterAddressDialog(&m_entered_server);
}
} // eventCallback