From 0f6dbbb4a08392f9315a69be6dbd8aecc954afdc Mon Sep 17 00:00:00 2001 From: Benau Date: Mon, 12 Mar 2018 16:51:30 +0800 Subject: [PATCH] Add default-disabled lobby chatting --- src/config/user_config.hpp | 4 ++ src/guiengine/widget.hpp | 1 + src/network/protocols/client_lobby.cpp | 16 ++++++ src/network/protocols/client_lobby.hpp | 1 + src/network/protocols/server_lobby.cpp | 23 ++++++++ src/network/protocols/server_lobby.hpp | 1 + src/states_screens/networking_lobby.cpp | 68 ++++++++++++++++++++++-- src/states_screens/networking_lobby.hpp | 16 +++--- src/states_screens/options_screen_ui.cpp | 19 ++++++- 9 files changed, 137 insertions(+), 12 deletions(-) diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index eae39eb11..8ea445e00 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -748,6 +748,10 @@ namespace UserConfigParams PARAM_PREFIX BoolUserConfigParam m_random_ports PARAM_DEFAULT(BoolUserConfigParam(true, "randrom-ports", &m_network_group, "Use random ports for client and server connection")); + PARAM_PREFIX BoolUserConfigParam m_lobby_chat + PARAM_DEFAULT(BoolUserConfigParam(false, "lobby-chat", + &m_network_group, "Enable chatting in networking lobby, if off than " + "no chat message will be displayed from any players.")); // ---- Gamemode setup PARAM_PREFIX UIntToUIntUserConfigParam m_server_ban_list diff --git a/src/guiengine/widget.hpp b/src/guiengine/widget.hpp index 7c67cc2ad..4aae5f2f4 100644 --- a/src/guiengine/widget.hpp +++ b/src/guiengine/widget.hpp @@ -659,6 +659,7 @@ namespace GUIEngine /** Gets called when the widget is active and got clicked. (Only works for button widgets for now.) */ virtual void onClick() { } + virtual irr::core::dimension2di getDimension() const { return irr::core::dimension2di(m_w, m_h); } }; diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 64a4c7d24..cc96cba48 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -18,6 +18,7 @@ #include "network/protocols/client_lobby.hpp" +#include "config/user_config.hpp" #include "config/player_manager.hpp" #include "karts/kart_properties_manager.hpp" #include "guiengine/modaldialog.hpp" @@ -236,6 +237,7 @@ bool ClientLobby::notifyEvent(Event* event) case LE_RACE_FINISHED: raceFinished(event); break; case LE_EXIT_RESULT: exitResultScreen(event); break; case LE_UPDATE_PLAYER_LIST: updatePlayerList(event); break; + case LE_CHAT: handleChat(event); break; default: return false; break; @@ -489,7 +491,21 @@ void ClientLobby::becomingServerOwner() } // becomingServerOwner //----------------------------------------------------------------------------- +void ClientLobby::handleChat(Event* event) +{ + if (!UserConfigParams::m_lobby_chat) + return; + std::string message; + event->data().decodeString(&message); + Log::info("ClientLobby", "%s", message.c_str()); + if (message.size() > 0) + { + NetworkingLobby::getInstance()->addMoreServerInfo( + StringUtils::utf8ToWide(message)); + } +} // handleChat +//----------------------------------------------------------------------------- /*! \brief Called when the server refuses the connection. * \param event : Event providing the information. * diff --git a/src/network/protocols/client_lobby.hpp b/src/network/protocols/client_lobby.hpp index 29d960394..1273d3c44 100644 --- a/src/network/protocols/client_lobby.hpp +++ b/src/network/protocols/client_lobby.hpp @@ -26,6 +26,7 @@ private: void playerReversedVote(Event* event); void playerLapsVote(Event* event); void updatePlayerList(Event* event); + void handleChat(Event* event); void becomingServerOwner(); TransportAddress m_server_address; diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 7e36407d1..faf30fd5f 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -159,6 +159,26 @@ bool ServerLobby::notifyEvent(Event* event) return true; } // notifyEvent +//----------------------------------------------------------------------------- +void ServerLobby::handleChat(Event* event) +{ + if (!event->getPeer()->hasPlayerProfiles()) + { + Log::warn("ServerLobby", "Unauthorized peer wants to chat."); + return; + } + core::stringw message; + event->data().decodeStringW(&message); + if (message.size() > 0) + { + NetworkString* chat = getNetworkString(); + chat->setSynchronous(true); + chat->addUInt8(LE_CHAT).encodeString(message); + sendMessageToPeersChangingToken(chat, /*reliable*/true); + delete chat; + } +} // handleChat + //----------------------------------------------------------------------------- void ServerLobby::kickHost(Event* event) { @@ -200,6 +220,7 @@ bool ServerLobby::notifyEventAsynchronous(Event* event) case LE_VOTE_LAPS: playerLapsVote(event); break; case LE_RACE_FINISHED_ACK: playerFinishedResult(event); break; case LE_KICK_HOST: kickHost(event); break; + case LE_CHAT: handleChat(event); break; default: break; } // switch } // if (event->getType() == EVENT_TYPE_MESSAGE) @@ -739,6 +760,7 @@ void ServerLobby::connectionRequested(Event* event) { NetworkString *message = getNetworkString(2); message->addUInt8(LE_CONNECTION_REFUSED).addUInt8(RR_BANNED); + peer->cleanPlayerProfiles(); peer->sendPacket(message); peer->reset(); delete message; @@ -791,6 +813,7 @@ void ServerLobby::connectionRequested(Event* event) NetworkString *message = getNetworkString(2); message->addUInt8(LE_CONNECTION_REFUSED) .addUInt8(RR_INCOMPATIBLE_DATA); + peer->cleanPlayerProfiles(); peer->sendPacket(message); peer->reset(); delete message; diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 87b78cd72..8a88ae5fa 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -96,6 +96,7 @@ private: void finishedLoadingWorldClient(Event *event); void startedRaceOnClient(Event *event); void kickHost(Event* event); + void handleChat(Event* event); void unregisterServer(); void createServerIdFile(); void updatePlayerList(); diff --git a/src/states_screens/networking_lobby.cpp b/src/states_screens/networking_lobby.cpp index ea8c5bda8..667528e55 100644 --- a/src/states_screens/networking_lobby.cpp +++ b/src/states_screens/networking_lobby.cpp @@ -19,8 +19,11 @@ #include +#include "config/user_config.hpp" #include "config/player_manager.hpp" #include "guiengine/CGUISpriteBank.hpp" +#include "guiengine/scalable_font.hpp" +#include "guiengine/widgets/button_widget.hpp" #include "guiengine/widgets/icon_button_widget.hpp" #include "guiengine/widgets/label_widget.hpp" #include "guiengine/widgets/list_widget.hpp" @@ -57,6 +60,7 @@ DEFINE_SCREEN_SINGLETON( NetworkingLobby ); // ---------------------------------------------------------------------------- NetworkingLobby::NetworkingLobby() : Screen("online/networking_lobby.stkgui") { + m_server_info_height = GUIEngine::getFont()->getDimension(L"X").Height; m_player_list = NULL; } // NetworkingLobby @@ -76,6 +80,9 @@ void NetworkingLobby::loadedFromFile() m_chat_box = getWidget("chat"); assert(m_chat_box != NULL); + m_send_button = getWidget("send"); + assert(m_send_button != NULL); + m_player_list = getWidget("players"); assert(m_player_list!= NULL); @@ -99,6 +106,18 @@ void NetworkingLobby::loadedFromFile() // --------------------------------------------------------------------------- void NetworkingLobby::beforeAddingWidget() { + if (!UserConfigParams::m_lobby_chat) + { + getWidget("chat")->setVisible(false); + getWidget("chat")->setActive(false); + getWidget("send")->setVisible(false); + } + else + { + getWidget("chat")->setVisible(true); + getWidget("chat")->setActive(true); + getWidget("send")->setVisible(true); + } } // beforeAddingWidget // ---------------------------------------------------------------------------- @@ -158,8 +177,29 @@ void NetworkingLobby::setJoinedServer(std::shared_ptr server) } // setJoinedServer // ---------------------------------------------------------------------------- -void NetworkingLobby::addMoreServerInfo(const core::stringw& info) +void NetworkingLobby::addMoreServerInfo(core::stringw info) { + assert(m_text_bubble->getDimension().Height > 10 && + m_text_bubble->getDimension().Width > 10); + while ((int)m_server_info.size() * m_server_info_height > + m_text_bubble->getDimension().Height - 10) + { + m_server_info.erase(m_server_info.begin()); + } + while ((int)GUIEngine::getFont()->getDimension(info.c_str()).Width > + m_text_bubble->getDimension().Width - 10) + { + int size = (m_text_bubble->getDimension().Width - 10) + / m_server_info_height; + assert(size > 0); + core::stringw new_info = info.subString(0, size); + m_server_info.push_back(new_info); + info = info.subString(new_info.size(), 80); + } + if (info.size() > 0) + { + m_server_info.push_back(info); + } } // addMoreServerInfo // ---------------------------------------------------------------------------- @@ -220,7 +260,30 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, } new NetworkUserDialog(host_online_ids[0], host_online_ids[1], m_player_list->getSelectionLabel()); - } // click on replay file + } // click on a user + else if (name == m_send_button->m_properties[PROP_ID]) + { + core::stringw text = m_chat_box->getText(); + // Max 80 words + text = text.subString(0, 80).trim(); + if (text.size() > 0) + { + NetworkString chat(PROTOCOL_LOBBY_ROOM); + chat.addUInt8(LobbyProtocol::LE_CHAT); + + core::stringw name; + PlayerProfile* player = PlayerManager::getCurrentPlayer(); + if (PlayerManager::getCurrentOnlineState() == + PlayerProfile::OS_SIGNED_IN) + name = PlayerManager::getCurrentOnlineUserName(); + else + name = player->getName(); + chat.encodeString(name + L": " + text); + + STKHost::get()->sendToServer(&chat, true); + } + m_chat_box->setText(""); + } // send chat message RibbonWidget* ribbon = dynamic_cast(widget); if (ribbon == NULL) return; @@ -247,7 +310,6 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, STKHost::get()->sendToServer(&start, true); } } - } // eventCallback // ---------------------------------------------------------------------------- diff --git a/src/states_screens/networking_lobby.hpp b/src/states_screens/networking_lobby.hpp index 3a11d050f..f28f69a78 100644 --- a/src/states_screens/networking_lobby.hpp +++ b/src/states_screens/networking_lobby.hpp @@ -26,7 +26,7 @@ class Server; namespace GUIEngine { - class Widget; + class ButtonWidget; class LabelWidget; class ListWidget; class IconButtonWidget; @@ -55,13 +55,15 @@ private: std::shared_ptr m_joined_server; std::vector m_server_info; + int m_server_info_height; - GUIEngine::IconButtonWidget * m_back_widget; - GUIEngine::LabelWidget * m_text_bubble; - GUIEngine::IconButtonWidget * m_exit_widget; - GUIEngine::IconButtonWidget *m_start_button; - GUIEngine::ListWidget *m_player_list; + GUIEngine::IconButtonWidget* m_back_widget; + GUIEngine::LabelWidget* m_text_bubble; + GUIEngine::IconButtonWidget* m_exit_widget; + GUIEngine::IconButtonWidget* m_start_button; + GUIEngine::ListWidget* m_player_list; GUIEngine::TextBoxWidget* m_chat_box; + GUIEngine::ButtonWidget* m_send_button; irr::gui::STKModifiedSpriteBank* m_icon_bank; @@ -92,7 +94,7 @@ public: virtual bool onEscapePressed() OVERRIDE; /** Used to insert each client chat message (reserved). */ - void addMoreServerInfo(const core::stringw& info); + void addMoreServerInfo(core::stringw info); void setJoinedServer(std::shared_ptr server); void updatePlayers(const std::vectorsetState(UserConfigParams::m_hw_report_enable); + getWidget("enable-lobby-chat") + ->setState(UserConfigParams::m_lobby_chat); + if(news->getState()) { stats_label->setVisible(true); @@ -289,17 +292,24 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con // If internet gets enabled, re-initialise the addon manager (which // happens in a separate thread) so that news.xml etc can be // downloaded if necessary. - CheckBoxWidget *stats = getWidget("enable-hw-report"); - LabelWidget *stats_label = getWidget("label-hw-report"); + CheckBoxWidget* stats = getWidget("enable-hw-report"); + LabelWidget* stats_label = getWidget("label-hw-report"); + CheckBoxWidget* chat = getWidget("enable-lobby-chat"); + LabelWidget* chat_label = getWidget("label-lobby-chat"); if(internet->getState()) { NewsManager::get()->init(false); stats->setVisible(true); stats_label->setVisible(true); stats->setState(UserConfigParams::m_hw_report_enable); + chat->setVisible(true); + stats->setState(UserConfigParams::m_lobby_chat); + chat_label->setVisible(true); } else { + chat->setVisible(false); + chat_label->setVisible(false); stats->setVisible(false); stats_label->setVisible(false); PlayerProfile* profile = PlayerManager::getCurrentPlayer(); @@ -314,6 +324,11 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con if(stats->getState()) HardwareStats::reportHardwareStats(); } + else if (name=="enable-lobby-chat") + { + CheckBoxWidget* chat = getWidget("enable-lobby-chat"); + UserConfigParams::m_lobby_chat = chat->getState(); + } else if (name=="show-login") { CheckBoxWidget* show_login = getWidget("show-login");