summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruntodesu <kirill@untode.su>2025-03-15 19:45:36 +0500
committeruntodesu <kirill@untode.su>2025-03-15 19:45:36 +0500
commitf7fbca1200015ddfd4de491e6c52996e6a3353d2 (patch)
treef43f9c9005ed86f7ac6b94628915889f2cb56611
parent0a396cde7f9a629038e1d7f85e582155744bc7c7 (diff)
downloadvoxelius-f7fbca1200015ddfd4de491e6c52996e6a3353d2.tar.bz2
voxelius-f7fbca1200015ddfd4de491e6c52996e6a3353d2.zip
After a year finally add direct connection screen
-rw-r--r--data/lang/lang.en_US.json7
-rw-r--r--game/client/CMakeLists.txt2
-rw-r--r--game/client/chat.cc10
-rw-r--r--game/client/direct_connection.cc132
-rw-r--r--game/client/direct_connection.hh11
-rw-r--r--game/client/game.cc11
-rw-r--r--game/client/gui_screen.hh16
-rw-r--r--game/client/play_menu.cc12
-rw-r--r--game/client/session.cc4
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)