diff options
| -rw-r--r-- | data/lang/lang.en_US.json | 7 | ||||
| -rw-r--r-- | game/client/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | game/client/chat.cc | 10 | ||||
| -rw-r--r-- | game/client/direct_connection.cc | 132 | ||||
| -rw-r--r-- | game/client/direct_connection.hh | 11 | ||||
| -rw-r--r-- | game/client/game.cc | 11 | ||||
| -rw-r--r-- | game/client/gui_screen.hh | 16 | ||||
| -rw-r--r-- | game/client/play_menu.cc | 12 | ||||
| -rw-r--r-- | game/client/session.cc | 4 |
9 files changed, 181 insertions, 24 deletions
diff --git a/data/lang/lang.en_US.json b/data/lang/lang.en_US.json index 90e1f20..24bd43a 100644 --- a/data/lang/lang.en_US.json +++ b/data/lang/lang.en_US.json @@ -20,6 +20,13 @@ "play_menu.status.init": "Unknown", "play_menu.status.ping": "Pinging", + "direct_connection.title": "Direct connection", + "direct_connection.connect": "Connect", + "direct_connection.cancel": "Cancel", + + "direct_connection.hostname": "Hostname", + "direct_connection.password": "Password", + "settings.checkbox.false": "OFF", "settings.checkbox.true": "ON", diff --git a/game/client/CMakeLists.txt b/game/client/CMakeLists.txt index 9339773..8fc9858 100644 --- a/game/client/CMakeLists.txt +++ b/game/client/CMakeLists.txt @@ -18,6 +18,8 @@ add_executable(vclient "${CMAKE_CURRENT_LIST_DIR}/const.hh" "${CMAKE_CURRENT_LIST_DIR}/crosshair.cc" "${CMAKE_CURRENT_LIST_DIR}/crosshair.hh" + "${CMAKE_CURRENT_LIST_DIR}/direct_connection.cc" + "${CMAKE_CURRENT_LIST_DIR}/direct_connection.hh" "${CMAKE_CURRENT_LIST_DIR}/experiments.cc" "${CMAKE_CURRENT_LIST_DIR}/experiments.hh" "${CMAKE_CURRENT_LIST_DIR}/factory.cc" diff --git a/game/client/chat.cc b/game/client/chat.cc index 177db08..e9becff 100644 --- a/game/client/chat.cc +++ b/game/client/chat.cc @@ -44,7 +44,7 @@ static void append_text_message(const std::string &sender, const std::string &te message.color = ImGui::GetStyleColorVec4(ImGuiCol_Text); history.push_back(message); - if(sfx_chat_message) { + if(sfx_chat_message && session::is_ingame()) { sound::play_ui(sfx_chat_message, false, 1.0f); } } @@ -57,7 +57,7 @@ static void append_player_join(const std::string &sender) message.color = ImGui::GetStyleColorVec4(ImGuiCol_DragDropTarget); history.push_back(message); - if(sfx_chat_message) { + if(sfx_chat_message && session::is_ingame()) { sound::play_ui(sfx_chat_message, false, 1.0f); } } @@ -70,7 +70,7 @@ static void append_player_leave(const std::string &sender, const std::string &re message.color = ImGui::GetStyleColorVec4(ImGuiCol_DragDropTarget); history.push_back(message); - if(sfx_chat_message) { + if(sfx_chat_message && session::is_ingame()) { sound::play_ui(sfx_chat_message, false, 1.0f); } } @@ -194,7 +194,7 @@ void client_chat::layout(void) ImGui::InputText("###chat.input", &chat_input); } - if((globals::gui_screen == GUI_SCREEN_NONE) || (globals::gui_screen == GUI_CHAT) || (globals::gui_screen == GUI_DEBUG_WINDOW)) { + if((globals::gui_screen == GUI_SCREEN_NONE) || (globals::gui_screen == GUI_CHAT)) { for(auto it = history.crbegin(); it < history.crend(); ++it) { auto text_size = ImGui::CalcTextSize(it->text.c_str(), it->text.c_str() + it->text.size(), false, window_size.x); auto rect_size = ImVec2(window_size.x, text_size.y + 2.0f * padding.y); @@ -255,7 +255,7 @@ void client_chat::print(const std::string &text) message.color = ImGui::GetStyleColorVec4(ImGuiCol_Text); history.push_back(message); - if(sfx_chat_message) { + if(sfx_chat_message && session::is_ingame()) { sound::play_ui(sfx_chat_message, false, 1.0f); } } diff --git a/game/client/direct_connection.cc b/game/client/direct_connection.cc new file mode 100644 index 0000000..3f2bf73 --- /dev/null +++ b/game/client/direct_connection.cc @@ -0,0 +1,132 @@ +#include "client/pch.hh" +#include "client/direct_connection.hh" + +#include "core/config.hh" +#include "core/strtools.hh" + +#include "shared/protocol.hh" + +#include "client/game.hh" +#include "client/glfw.hh" +#include "client/globals.hh" +#include "client/gui_screen.hh" +#include "client/language.hh" +#include "client/session.hh" + +constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration; + +static std::string str_title; +static std::string str_connect; +static std::string str_cancel; + +static std::string str_hostname; +static std::string str_password; + +static std::string direct_hostname; +static std::string direct_password; + +static void on_glfw_key(const GlfwKeyEvent &event) +{ + if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) { + if(globals::gui_screen == GUI_DIRECT_CONNECTION) { + globals::gui_screen = GUI_PLAY_MENU; + return; + } + } +} + +static void on_language_set(const LanguageSetEvent &event) +{ + str_title = language::resolve("direct_connection.title"); + str_connect = language::resolve_gui("direct_connection.connect"); + str_cancel = language::resolve_gui("direct_connection.cancel"); + + str_hostname = language::resolve("direct_connection.hostname"); + str_password = language::resolve("direct_connection.password"); +} + +static void connect_to_server(void) +{ + auto parts = strtools::split(direct_hostname, ":"); + std::string parsed_hostname; + std::uint16_t parsed_port; + + if(!parts[0].empty()) + parsed_hostname = parts[0]; + else parsed_hostname = std::string("localhost"); + + if(parts.size() >= 2) + parsed_port = cxpr::clamp<std::uint16_t>(strtoul(parts[1].c_str(), nullptr, 10), 1024, UINT16_MAX); + else parsed_port = protocol::PORT; + + session::connect(parsed_hostname.c_str(), parsed_port, direct_password.c_str()); +} + +void direct_connection::init(void) +{ + globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>(); + globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>(); +} + +void direct_connection::layout(void) +{ + auto viewport = ImGui::GetMainViewport(); + auto window_start = ImVec2(0.25f * viewport->Size.x, 0.20f * viewport->Size.y); + auto window_size = ImVec2(0.50f * viewport->Size.x, 0.80f * viewport->Size.y); + + ImGui::SetNextWindowPos(window_start); + ImGui::SetNextWindowSize(window_size); + + if(ImGui::Begin("###UIDirectConnect", nullptr, WINDOW_FLAGS)) { + const float title_width = ImGui::CalcTextSize(str_title.c_str()).x; + ImGui::SetCursorPosX(0.5f * (window_size.x - title_width)); + ImGui::TextUnformatted(str_title.c_str()); + + ImGui::Dummy(ImVec2(0.0f, 16.0f * globals::gui_scale)); + + ImGuiInputTextFlags hostname_flags = ImGuiInputTextFlags_CharsNoBlank; + + if(client_game::streamer_mode.get_value()) { + // Hide server hostname to avoid things like + // followers flooding the server that is streamed online + hostname_flags |= ImGuiInputTextFlags_Password; + } + + auto avail_width = ImGui::GetContentRegionAvail().x; + + ImGui::PushItemWidth(avail_width); + + ImGui::InputText("###UIDirectConnect_hostname", &direct_hostname, hostname_flags); + + if(ImGui::BeginItemTooltip()) { + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f); + ImGui::TextUnformatted(str_hostname.c_str()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + ImGui::InputText("###UIDirectConnect_password", &direct_password, ImGuiInputTextFlags_Password); + + if(ImGui::BeginItemTooltip()) { + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f); + ImGui::TextUnformatted(str_password.c_str()); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + + ImGui::PopItemWidth(); + + ImGui::Dummy(ImVec2(0.0f, 4.0f * globals::gui_scale)); + + ImGui::BeginDisabled(strtools::is_whitespace(direct_hostname)); + if(ImGui::Button(str_connect.c_str(), ImVec2(avail_width, 0.0f))) + connect_to_server(); + ImGui::EndDisabled(); + + if(ImGui::Button(str_cancel.c_str(), ImVec2(avail_width, 0.0f))) { + globals::gui_screen = GUI_PLAY_MENU; + } + } + + ImGui::End(); +} diff --git a/game/client/direct_connection.hh b/game/client/direct_connection.hh new file mode 100644 index 0000000..f94bcaf --- /dev/null +++ b/game/client/direct_connection.hh @@ -0,0 +1,11 @@ +#ifndef CLIENT_DIRECT_CONNECTION_HH +#define CLIENT_DIRECT_CONNECTION_HH 1 +#pragma once + +namespace direct_connection +{ +void init(void); +void layout(void); +} // namespace direct_connection + +#endif /* CLIENT_DIRECT_CONNECTION_HH */ diff --git a/game/client/game.cc b/game/client/game.cc index dcd463c..e0e02d1 100644 --- a/game/client/game.cc +++ b/game/client/game.cc @@ -34,6 +34,7 @@ #include "client/chunk_visibility.hh" #include "client/const.hh" #include "client/crosshair.hh" +#include "client/direct_connection.hh" #include "client/experiments.hh" #include "client/gamepad.hh" #include "client/glfw.hh" @@ -329,6 +330,7 @@ void client_game::init(void) play_menu::init(); progress_bar::init(); message_box::init(); + direct_connection::init(); crosshair::init(); hotbar::init(); @@ -614,7 +616,7 @@ void client_game::layout(void) background::layout(); } - if(!globals::gui_screen || (globals::gui_screen == GUI_CHAT) || (globals::gui_screen == GUI_DEBUG_WINDOW)) { + if(!globals::gui_screen || (globals::gui_screen == GUI_CHAT)) { if(toggles::draw_metrics && !client_game::hide_hud) { // This contains Minecraft-esque debug information // about the hardware, world state and other @@ -635,7 +637,7 @@ void client_game::layout(void) } if(globals::gui_screen) { - if(session::is_ingame() && (globals::gui_screen != GUI_CHAT) && (globals::gui_screen != GUI_DEBUG_WINDOW)) { + if(session::is_ingame() && (globals::gui_screen != GUI_CHAT)) { const float width_f = static_cast<float>(globals::width); const float height_f = static_cast<float>(globals::height); const ImU32 darken = ImGui::GetColorU32(ImVec4(0.00f, 0.00f, 0.00f, 0.75f)); @@ -652,12 +654,15 @@ void client_game::layout(void) case GUI_SETTINGS: settings::layout(); break; - case GUI_PROGRESS: + case GUI_PROGRESS_BAR: progress_bar::layout(); break; case GUI_MESSAGE_BOX: message_box::layout(); break; + case GUI_DIRECT_CONNECTION: + direct_connection::layout(); + break; } } } diff --git a/game/client/gui_screen.hh b/game/client/gui_screen.hh index 2090743..0ee7b44 100644 --- a/game/client/gui_screen.hh +++ b/game/client/gui_screen.hh @@ -2,13 +2,13 @@ #define CLIENT_GUI_SCREEN_HH 1 #pragma once -constexpr static unsigned int GUI_SCREEN_NONE = 0x0000U; -constexpr static unsigned int GUI_MAIN_MENU = 0x0001U; -constexpr static unsigned int GUI_PLAY_MENU = 0x0002U; -constexpr static unsigned int GUI_SETTINGS = 0x0003U; -constexpr static unsigned int GUI_PROGRESS = 0x0004U; -constexpr static unsigned int GUI_MESSAGE_BOX = 0x0005U; -constexpr static unsigned int GUI_CHAT = 0x0006U; -constexpr static unsigned int GUI_DEBUG_WINDOW = 0x0007U; +constexpr static unsigned int GUI_SCREEN_NONE = 0x0000U; +constexpr static unsigned int GUI_MAIN_MENU = 0x0001U; +constexpr static unsigned int GUI_PLAY_MENU = 0x0002U; +constexpr static unsigned int GUI_SETTINGS = 0x0003U; +constexpr static unsigned int GUI_PROGRESS_BAR = 0x0004U; +constexpr static unsigned int GUI_MESSAGE_BOX = 0x0005U; +constexpr static unsigned int GUI_CHAT = 0x0006U; +constexpr static unsigned int GUI_DIRECT_CONNECTION = 0x0007U; #endif /* CLIENT_GUI_SCREEN_HH */ diff --git a/game/client/play_menu.cc b/game/client/play_menu.cc index 1ad6e52..4c1d2cd 100644 --- a/game/client/play_menu.cc +++ b/game/client/play_menu.cc @@ -72,14 +72,14 @@ static bool needs_focus; static void parse_hostname(ServerStatusItem *item, const std::string &hostname) { - const std::vector<std::string> parts = strtools::split(hostname, ":"); + auto parts = strtools::split(hostname, ":"); if(!parts[0].empty()) item->hostname = parts[0]; else item->hostname = std::string("localhost"); if(parts.size() >= 2) - item->port = cxpr::clamp<std::uint16_t>(strtoul(parts[1].c_str(), nullptr, 10), 0x0000, UINT16_MAX); + item->port = cxpr::clamp<std::uint16_t>(strtoul(parts[1].c_str(), nullptr, 10), 1024, UINT16_MAX); else item->port = protocol::PORT; } @@ -329,7 +329,7 @@ static void layout_servers(void) static void layout_servers_buttons(void) { - const float avail_width = ImGui::GetContentRegionAvail().x; + auto avail_width = ImGui::GetContentRegionAvail().x; // Can only join when selected and not editing ImGui::BeginDisabled(!selected_server || editing_server); @@ -337,13 +337,13 @@ static void layout_servers_buttons(void) join_selected_server(); ImGui::EndDisabled(); ImGui::SameLine(); - + // Can only connect directly when not editing anything ImGui::BeginDisabled(editing_server); if(ImGui::Button(str_connect.c_str(), ImVec2(-1.00f, 0.0f))) - spdlog::debug("UNDONE: direct connect is not implemented!"); + globals::gui_screen = GUI_DIRECT_CONNECTION; ImGui::EndDisabled(); - + // Can only add when not editing anything ImGui::BeginDisabled(editing_server); if(ImGui::Button(str_add.c_str(), ImVec2(-0.75f * avail_width, 0.0f))) diff --git a/game/client/session.cc b/game/client/session.cc index 33e27b5..3371889 100644 --- a/game/client/session.cc +++ b/game/client/session.cc @@ -244,7 +244,7 @@ void session::connect(const char *host, std::uint16_t port, const char *password globals::gui_screen = GUI_PLAY_MENU; }); - globals::gui_screen = GUI_PROGRESS; + globals::gui_screen = GUI_PROGRESS_BAR; } void session::disconnect(const char *reason) @@ -292,7 +292,7 @@ void session::send_login_request(void) server_password_hash = UINT64_MAX; progress_bar::set_title("connecting.logging_in"); - globals::gui_screen = GUI_PROGRESS; + globals::gui_screen = GUI_PROGRESS_BAR; } bool session::is_ingame(void) |
