A separate button for info/announcements.

Rather than having everything in the MOTD, this adds a separate button that will popup a window which will have most of this information in two tabs:
* General server information, such as a link to the CoC.
* Announcements, such as tournaments and new versions being released.

The information on this new window will be stored in the new `server_config` database table.
The MOTD will then just be a short greeting instead of the several lines that are shown currently.

Additionally, now the motd will only be displayed in the lobby chat the first time the user logs on.
This commit is contained in:
Pentarctagon 2020-04-22 12:03:42 -05:00 committed by Pentarctagon
parent 4a3177b228
commit f996803cf6
13 changed files with 462 additions and 1 deletions

View file

@ -445,6 +445,19 @@
[/column]
[/row]
[row]
[column]
border = "all"
border_size = 5
horizontal_grow = true
[button]
id = "server_info"
definition = "large"
label = _ "Information"
[/button]
[/column]
[/row]
[row]
[column]
border = "all"
@ -586,6 +599,17 @@
[/button]
[/column]
[column]
border = "all"
border_size = 5
horizontal_grow = true
[button]
id = "server_info"
definition = "default"
label = _ "Information"
[/button]
[/column]
[column]
grow_factor = 0
border = "all"

View file

@ -0,0 +1,271 @@
#textdomain wesnoth-lib
#define _GUI_HORIZONTAL_TAB ID
[row]
[column]
horizontal_grow = true
vertical_alignment = top
[grid]
[row]
grow_factor = 0
[column]
grow_factor = 0
border = "all"
border_size = 5
horizontal_alignment = "left"
[label]
id = {ID}
definition = "default"
label = ""
use_markup = true
wrap = true
[/label]
[/column]
[/row]
[/grid]
[/column]
[/row]
#enddef
[window]
id = "server_info"
description = "A window to show announcements and other information in the MP lobby."
[resolution]
definition = "default"
maximum_width = 800
maximum_height = 600
[tooltip]
id = "tooltip"
[/tooltip]
[helptip]
id = "tooltip"
[/helptip]
[linked_group]
id = "tabs"
fixed_width = true
fixed_height = true
[/linked_group]
[grid]
[row]
[column]
border = "all"
border_size = 5
horizontal_alignment = "left"
vertical_alignment = "top"
[label]
id = "asdf"
definition = "title"
label = _ "Server Information"
[/label]
[/column]
[/row]
[row]
[column]
horizontal_alignment = left
vertical_alignment = top
[grid]
[row]
[column]
horizontal_grow = true
vertical_alignment = top
[grid]
[row]
[column]
border = all
border_size = 5
[horizontal_listbox]
id = "tab_bar"
horizontal_scrollbar_mode = "never"
vertical_scrollbar_mode = "never"
[list_definition]
[row]
[column]
[toggle_panel]
linked_group = "tabs"
[grid]
[row]
[column]
border = all
border_size = 5
[spacer][/spacer]
[/column]
[column]
grow_factor = 1
border = all
border_size = 5
[label]
id = "tab_label"
wrap = true
[/label]
[/column]
[column]
border = all
border_size = 5
[spacer][/spacer]
[/column]
[/row]
[/grid]
[/toggle_panel]
[/column]
[/row]
[/list_definition]
[list_data]
[row]
[column]
[widget]
id = "tab_label"
label = _ "Announcements"
[/widget]
[/column]
[/row]
[row]
[column]
[widget]
id = "tab_label"
label = _ "General"
[/widget]
[/column]
[/row]
[/list_data]
[/horizontal_listbox]
[/column]
[/row]
[row]
grow_factor = 1
[column]
grow_factor = 1
horizontal_grow = true
[stacked_widget]
id = tabs_container
[layer]
{_GUI_HORIZONTAL_TAB announcements}
[/layer]
[layer]
{_GUI_HORIZONTAL_TAB server_information}
[/layer]
[/stacked_widget]
[/column]
[/row]
[/grid]
[/column]
[/row]
[/grid]
[/column]
[/row]
[row]
grow_factor = 0
[column]
horizontal_grow = true
[grid]
[row]
grow_factor = 0
[column]
grow_factor = 1
horizontal_alignment = right
border = "all"
border_size = 5
[button]
id = "ok"
definition = "default"
label = _ "Close"
[/button]
[/column]
[/row]
[/grid]
[/column]
[/row]
[/grid]
[/resolution]
[/window]
#undef _GUI_HORIZONTAL_TAB

View file

@ -196,6 +196,7 @@ gui/dialogs/game_load.cpp
gui/dialogs/game_save.cpp
gui/dialogs/game_stats.cpp
gui/dialogs/game_version_dialog.cpp
gui/dialogs/server_info_dialog.cpp
gui/dialogs/gamestate_inspector.cpp
gui/dialogs/help_browser.cpp
gui/dialogs/hotkey_bind.cpp

View file

@ -35,6 +35,7 @@
#include "gui/widgets/toggle_button.hpp"
#include "gui/widgets/toggle_panel.hpp"
#include "gui/widgets/tree_view_node.hpp"
#include "gui/dialogs/server_info_dialog.hpp"
#include "addon/client.hpp"
#include "addon/manager_ui.hpp"
@ -760,6 +761,10 @@ void mp_lobby::pre_show(window& window)
find_widget<button>(&window, "observe_global", false),
std::bind(&mp_lobby::enter_selected_game, this, DO_OBSERVE));
connect_signal_mouse_left_click(
find_widget<button>(&window, "server_info", false),
std::bind(&mp_lobby::show_server_info, this));
find_widget<button>(&window, "observe_global", false).set_active(false);
menu_button& replay_options = find_widget<menu_button>(&window, "replay_options", false);
@ -886,6 +891,14 @@ void mp_lobby::process_network_data(const config& data)
process_gamelist(data);
} else if(const config& gamelist_diff = data.child("gamelist_diff")) {
process_gamelist_diff(gamelist_diff);
} else if(const config& info = data.child("message")) {
if(info["type"] == "server_info") {
server_information_ = info["message"].str();
return;
} else if(info["type"] == "announcements") {
announcements_ = info["message"].str();
return;
}
}
chatbox_->process_network_data(data);
@ -1053,6 +1066,11 @@ void mp_lobby::show_preferences_button_callback(window& window)
refresh_lobby();
}
void mp_lobby::show_server_info()
{
server_info::display(server_information_, announcements_);
}
void mp_lobby::game_filter_reload()
{
lobby_info_.clear_game_filter();

View file

@ -138,6 +138,8 @@ private:
void show_preferences_button_callback(window& window);
void show_server_info();
void refresh_lobby();
void game_filter_reload();
@ -214,6 +216,9 @@ private:
int joined_game_id_;
friend struct lobby_delay_gamelist_update_guard;
std::string server_information_;
std::string announcements_;
};
} // namespace dialogs

View file

@ -0,0 +1,62 @@
/*
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
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 2 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.
See the COPYING file for more details.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "gui/dialogs/server_info_dialog.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/widgets/label.hpp"
#include "gui/widgets/listbox.hpp"
#include "gui/widgets/stacked_widget.hpp"
#include "gui/widgets/window.hpp"
namespace gui2
{
namespace dialogs
{
REGISTER_DIALOG(server_info)
server_info::server_info(const std::string& info, const std::string& announcements)
: server_information_(info)
, announcements_(announcements)
{
}
void server_info::pre_show(window& window)
{
find_widget<label>(&window, "server_information", false).set_label(server_information_);
find_widget<label>(&window, "announcements", false).set_label(announcements_);
stacked_widget& pager = find_widget<stacked_widget>(&window, "tabs_container", false);
pager.select_layer(0);
listbox& tab_bar = find_widget<listbox>(&window, "tab_bar", false);
VALIDATE(tab_bar.get_item_count() == pager.get_layer_count(), "Tab bar and container size mismatch");
connect_signal_notify_modified(tab_bar, std::bind(&server_info::tab_switch_callback, this, std::ref(window)));
}
void server_info::tab_switch_callback(window& window)
{
stacked_widget& pager = find_widget<stacked_widget>(&window, "tabs_container", false);
listbox& tab_bar = find_widget<listbox>(&window, "tab_bar", false);
pager.select_layer(std::max<int>(0, tab_bar.get_selected_row()));
}
}
}

View file

@ -0,0 +1,55 @@
/*
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
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 2 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.
See the COPYING file for more details.
*/
#pragma once
#include "gui/dialogs/modal_dialog.hpp"
namespace gui2
{
class listbox;
namespace dialogs
{
class server_info : public modal_dialog
{
public:
/**
* Constructor.
*/
server_info(const std::string& info, const std::string& announcement);
/**
* The display function.
*
* See @ref modal_dialog for more information.
*/
static void display(const std::string& info, const std::string& announcements)
{
server_info(info, announcements).show();
}
private:
/** Inherited from modal_dialog, implemented by REGISTER_DIALOG. */
virtual const std::string& window_id() const override;
/** Inherited from modal_dialog. */
virtual void pre_show(window& window) override;
void tab_switch_callback(window& window);
const std::string& server_information_;
const std::string& announcements_;
};
}
}

View file

@ -46,6 +46,7 @@ fuh::fuh(const config& c)
, db_game_player_info_table_(c["db_game_player_info_table"].str())
, db_game_modification_info_table_(c["db_game_modification_info_table"].str())
, db_user_group_table_(c["db_user_group_table"].str())
, db_tournament_query_(c["db_tournament_query"].str())
, mp_mod_group_(0)
, conn(mysql_init(nullptr))
{
@ -418,6 +419,17 @@ std::string fuh::get_uuid(){
}
}
// TODO - WIP
// select substring(substring_index(topic_title, ']', 1), 2) as STATUS, concat('https://r.wesnoth.org/t', topic_id) as URL, substring_index(topic_title, ']', -1) as TITLE from tournaments where forum_id = 70 and (topic_title like '[Open]%' or topic_title like '[In Progress]%')
std::string fuh::get_tournaments(){
try {
return "";
} catch (const sql_error& e) {
ERR_UH << "TBD:" << e.message << std::endl;
return "";
}
}
void fuh::db_insert_game_info(const std::string& uuid, int game_id, const std::string& version, const std::string& name, const std::string& map_name, const std::string& era_name, int reload, int observers, int is_public, int has_password){
try {
prepared_statement<void>("INSERT INTO `" + db_game_info_table_ + "`(INSTANCE_UUID, GAME_ID, INSTANCE_VERSION, GAME_NAME, MAP_NAME, ERA_NAME, RELOAD, OBSERVERS, PUBLIC, PASSWORD) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",

View file

@ -70,6 +70,7 @@ class fuh : public user_handler {
bool use_phpbb_encryption() const { return true; }
std::string get_uuid();
std::string get_tournaments();
void db_insert_game_info(const std::string& uuid, int game_id, const std::string& version, const std::string& name, const std::string& map_name, const std::string& era_name, int reload, int observers, int is_public, int has_password);
void db_update_game_end(const std::string& uuid, int game_id, const std::string& replay_location);
void db_insert_game_player_info(const std::string& uuid, int game_id, const std::string& username, int side_number, int is_host, const std::string& faction, const std::string& version, const std::string& source, const std::string& current_user);
@ -91,6 +92,7 @@ class fuh : public user_handler {
std::time_t retrieve_ban_duration_internal(const std::string& col, unsigned int detail);
std::string db_name_, db_host_, db_user_, db_password_, db_users_table_, db_banlist_table_, db_extra_table_, db_game_info_table_, db_game_player_info_table_, db_game_modification_info_table_, db_user_group_table_;
std::string db_tournament_query_;
unsigned int mp_mod_group_;
MYSQL *conn;

View file

@ -238,6 +238,8 @@ server::server(int port,
, disallowed_names_()
, admin_passwd_()
, motd_()
, announcements_()
, information_()
, default_max_messages_(0)
, default_time_period_(0)
, concurrent_connections_(0)
@ -454,6 +456,8 @@ void server::load_config()
admin_passwd_ = cfg_["passwd"].str();
motd_ = cfg_["motd"].str();
information_ = cfg_["information"].str();
announcements_ = cfg_["announcements"].str();
lan_server_ = cfg_["lan_server"].to_time_t(0);
deny_unregistered_login_ = cfg_["deny_unregistered_login"].to_bool();
@ -530,6 +534,7 @@ void server::load_config()
if(const config& user_handler = cfg_.child("user_handler")) {
user_handler_.reset(new fuh(user_handler));
uuid_ = user_handler_->get_uuid();
announcements_ += user_handler_->get_tournaments();
}
#endif
}
@ -996,8 +1001,10 @@ void server::add_player(socket_ptr socket, const wesnothd::player& player)
send_to_player(socket, games_and_users_list_);
if(!motd_.empty()) {
send_server_message(socket, motd_, "motd");
send_server_message(socket, motd_+'\n'+announcements_, "motd");
}
send_server_message(socket, information_, "server_info");
send_server_message(socket, announcements_, "announcements");
if(version_info(player.version()) < secure_version ){
send_server_message(socket, "You are using version " + player.version() + " which has known security issues that can be used to compromise your computer. We strongly recommend updating to a Wesnoth version " + secure_version.str() + " or newer!", "alert");
}

View file

@ -140,6 +140,8 @@ private:
std::vector<std::string> disallowed_names_;
std::string admin_passwd_;
std::string motd_;
std::string announcements_;
std::string information_;
std::size_t default_max_messages_;
std::size_t default_time_period_;
std::size_t concurrent_connections_;

View file

@ -135,6 +135,7 @@ class user_handler {
virtual bool use_phpbb_encryption() const =0;
virtual std::string get_uuid() =0;
virtual std::string get_tournaments() =0;
virtual void db_insert_game_info(const std::string& uuid, int game_id, const std::string& version, const std::string& name, const std::string& map_name, const std::string& era_name, int reload, int observers, int is_public, int has_password) =0;
virtual void db_update_game_end(const std::string& uuid, int game_id, const std::string& replay_location) =0;
virtual void db_insert_game_player_info(const std::string& uuid, int game_id, const std::string& username, int side_number, int is_host, const std::string& faction, const std::string& version, const std::string& source, const std::string& current_user) =0;

View file

@ -539,6 +539,7 @@ BOOST_AUTO_TEST_CASE(test_gui2)
"mp_change_control", // Basically useless without a game_board object, so disabling
"game_stats", // segfault with LTO
"gamestate_inspector", // segfault with LTO
"server_info",
};
std::vector<std::string> missing;