diff --git a/scripts/gui/main_menu.mjs b/scripts/gui/main_menu.mjs index 1481c53541f..ee56233059a 100644 --- a/scripts/gui/main_menu.mjs +++ b/scripts/gui/main_menu.mjs @@ -25,6 +25,45 @@ export function runMenuSetup(){ common.playButtonPressSound(); newGame(); }, true); + document.getElementById("extrasButton").addEventListener("click", (event) => { + event.stopPropagation(); + $("#mainMenu").slideUp("fast", () => { + $("#extrasMenu").slideDown("fast"); + }); + }, true); + document.getElementById("backFromExtras").addEventListener("click", (event) => { + event.stopPropagation(); + $("#extrasMenu").slideUp("fast", () => { + $("#mainMenu").slideDown("fast"); + }); + }, true); + document.getElementById("toMultiplayerProtoButton").addEventListener("click", (event) => { + event.stopPropagation(); + $("#extrasMenu").slideUp("fast", () => { + $("#serverConnectingMenu").slideDown("fast"); + }); + }, true); + document.getElementById("backFromConnecting").addEventListener("click", (event) => { + event.stopPropagation(); + $("#serverConnectingMenu").slideUp("fast", () => { + $("#extrasMenu").slideDown("fast"); + }); + }, true); + document.getElementById("backFromConnecting").addEventListener("click", (event) => { + event.stopPropagation(); + $("#serverConnectingMenu").slideUp("fast", () => { + $("#extrasMenu").slideDown("fast"); + }); + }, true); + document.getElementById("connectToServerButton").addEventListener("click", (event) => { + event.stopPropagation(); + connectToSelectedServerURL(); + }, true); + document.getElementById("disconnectFromServer").addEventListener("click", (event) => { + event.stopPropagation(); + disconnectFromCurrentServer(); + }, true); + document.addEventListener("keydown", (event) => { if(event.key === "Escape"){ @@ -50,6 +89,11 @@ export function runMenuSetup(){ doExitToMenu(); }); + // Server status message display + Leviathan.OnGeneric("ConnectStatusMessage", (event, vars) => { + handleConnectionStatusEvent(vars); + }); + // Start intro video Leviathan.PlayCutscene("Data/Videos/intro.mkv", onIntroEnded, onIntroEnded); @@ -150,6 +194,49 @@ function newGame(){ } } +function connectToSelectedServerURL(){ + // The url is from this textbox + const url = document.getElementById("connectServerURLInput").value; + + if(!url) + return; + + if(common.isInEngine()){ + + Thrive.connectToServer(url); + + } else { + + handleConnectionStatusEvent({ + show: true, server: url, + message: "This is the GUI in a browser and can't actually connect" + }); + } +} + +function disconnectFromCurrentServer(){ + if(common.isInEngine()){ + + Thrive.disconnectFromServer(); + + } else { + + handleConnectionStatusEvent({show: false}); + } +} + +function handleConnectionStatusEvent(event){ + if(event.show){ + document.getElementById("serverConnectPopup").style.display = "flex"; + } else { + document.getElementById("serverConnectPopup").style.display = "none"; + } + + if(event.server) + document.getElementById("currentServerAddress").innerText = event.server; + document.getElementById("currentConnectionStatusMessage").innerText = event.message; +} + function onMicrobeIntroEnded(error){ if(error) diff --git a/scripts/gui/thrive_gui.html b/scripts/gui/thrive_gui.html index dd9e604237d..d870efa87d0 100644 --- a/scripts/gui/thrive_gui.html +++ b/scripts/gui/thrive_gui.html @@ -49,11 +49,39 @@ - + + + + + + + + + + JavaScript not loaded... diff --git a/scripts/gui/thrive_style.css b/scripts/gui/thrive_style.css index 9e00d51be6f..77d0e0e4cd1 100644 --- a/scripts/gui/thrive_style.css +++ b/scripts/gui/thrive_style.css @@ -205,6 +205,28 @@ video { vertical-align: middle; line-height: 40px; font-size: 15pt; + margin-left: auto; + margin-right: auto; +} + +.MenuTextBox { + background: rgb(0, 125, 125, 0.8); + border: 1px solid rgb(112, 159, 159, 0.6); + color: white; + height: 32px; + font-size: 18pt; + margin-bottom: 3px; +} + +.MenuDialogBox { + width: 500px; + height: 160px; + border-radius: 3px; + background: rgb(0, 125, 125, 0.9); + border: 2px solid rgb(112, 159, 159, 0.6); + display: flex; + align-items: center; + flex-direction: column; } .DisabledButton { @@ -556,6 +578,7 @@ video { background-color: rgb(0, 0, 0, 0.7); z-index: 1; display: flex; + align-items: center; justify-content: center; } diff --git a/src/ThriveGame.cpp b/src/ThriveGame.cpp index ec93defb5ed..f805e6ca072 100644 --- a/src/ThriveGame.cpp +++ b/src/ThriveGame.cpp @@ -623,6 +623,100 @@ void m_impl->m_cellStage->GetMicrobeCameraSystem().changeCameraOffset( amount); } +// ------------------------------------ // +void + ThriveGame::connectToServer(const std::string& url) +{ + LOG_INFO("Connecting to server at: " + url); + + if(m_network->IsConnected()) { + disconnectFromServer( + false, "Disconnect by user, joining another server"); + } + + auto connection = m_network->GetOwner()->OpenConnectionTo(url); + + if(!connection) { + + Leviathan::GenericEvent::pointer event = + new Leviathan::GenericEvent("ConnectStatusMessage"); + + auto vars = event->GetVariables(); + + vars->Add(std::make_shared( + "show", new Leviathan::BoolBlock(true))); + vars->Add(std::make_shared("message", + new Leviathan::StringBlock("Invalid address specified"))); + + Engine::Get()->GetEventHandler()->CallEvent(event.detach()); + + } else { + + if(!m_network->JoinServer(connection)) { + + Leviathan::GenericEvent::pointer event = + new Leviathan::GenericEvent("ConnectStatusMessage"); + + auto vars = event->GetVariables(); + + vars->Add(std::make_shared( + "show", new Leviathan::BoolBlock(true))); + vars->Add(std::make_shared("message", + new Leviathan::StringBlock( + "Unknown error from JoinServer (try disconnecting?)"))); + + Engine::Get()->GetEventHandler()->CallEvent(event.detach()); + return; + } + + Leviathan::GenericEvent::pointer event = + new Leviathan::GenericEvent("ConnectStatusMessage"); + + auto vars = event->GetVariables(); + + vars->Add(std::make_shared( + "show", new Leviathan::BoolBlock(true))); + vars->Add(std::make_shared( + "server", new Leviathan::StringBlock(url))); + vars->Add(std::make_shared( + "message", new Leviathan::StringBlock("Opening connection"))); + + Engine::Get()->GetEventHandler()->CallEvent(event.detach()); + } +} + +void + ThriveGame::disconnectFromServer(bool userInitiated, + const std::string& reason) +{ + LOG_INFO("Initiating disconnect from server"); + m_network->DisconnectFromServer(reason); + + if(!userInitiated) { + Leviathan::GenericEvent::pointer event = + new Leviathan::GenericEvent("ConnectStatusMessage"); + + auto vars = event->GetVariables(); + + vars->Add(std::make_shared( + "show", new Leviathan::BoolBlock(true))); + vars->Add(std::make_shared( + "message", new Leviathan::StringBlock("Disconnected: " + reason))); + + Engine::Get()->GetEventHandler()->CallEvent(event.detach()); + } else { + Leviathan::GenericEvent::pointer event = + new Leviathan::GenericEvent("ConnectStatusMessage"); + + auto vars = event->GetVariables(); + + // This hides it + vars->Add(std::make_shared( + "show", new Leviathan::BoolBlock(false))); + + Engine::Get()->GetEventHandler()->CallEvent(event.detach()); + } +} // ------------------------------------ // void diff --git a/src/ThriveGame.h b/src/ThriveGame.h index 3b1f9162839..05c88e7293d 100644 --- a/src/ThriveGame.h +++ b/src/ThriveGame.h @@ -71,6 +71,17 @@ class ThriveGame : public Leviathan::ClientApplication, public ThriveCommon { void onZoomChange(float amount); + + // ------------------------------------ // + //! \brief Begins connecting to server at url + void + connectToServer(const std::string& url); + + //! \brief Disconnects from current server + void + disconnectFromServer(bool userInitiated, + const std::string& reason = "Disconnect by user"); + // ------------------------------------ // // Hooking into the engine, and overridden methods from base application // etc. diff --git a/src/thrive_js_interface.cpp b/src/thrive_js_interface.cpp index e6850e8ec43..75ead1d33d1 100644 --- a/src/thrive_js_interface.cpp +++ b/src/thrive_js_interface.cpp @@ -109,6 +109,28 @@ bool auto args = message->GetArgumentList(); args->SetString(0, "exitToMenuClicked"); + Owner->SendCustomExtensionMessage(message); + return true; + } else if(name == "connectToServer") { + + if(arguments.size() < 1 || !arguments[0]->IsString()) { + // Invalid arguments // + exception = "Invalid arguments passed, expected: string"; + return true; + } + + auto message = CefProcessMessage::Create("Custom"); + auto args = message->GetArgumentList(); + args->SetString(0, "connectToServer"); + args->SetString(1, arguments[0]->GetStringValue()); + + Owner->SendCustomExtensionMessage(message); + return true; + } else if(name == "disconnectFromServer") { + auto message = CefProcessMessage::Create("Custom"); + auto args = message->GetArgumentList(); + args->SetString(0, "disconnectFromServer"); + Owner->SendCustomExtensionMessage(message); return true; } @@ -159,7 +181,16 @@ bool ThriveGame::Get()->exitToMenuClicked(); return true; + } else if(customType == "connectToServer") { + + ThriveGame::Get()->connectToServer(args->GetString(1)); + return true; + } else if(customType == "disconnectFromServer") { + + ThriveGame::Get()->disconnectFromServer(true); + return true; } + // Not ours return false; } diff --git a/src/thrive_v8_extension.js b/src/thrive_v8_extension.js index ca3cc99abb7..2fb037fcc14 100644 --- a/src/thrive_v8_extension.js +++ b/src/thrive_v8_extension.js @@ -26,4 +26,10 @@ var Thrive = {}; native function exitToMenuClicked(); Thrive.exitToMenuClicked = exitToMenuClicked; + native function connectToServer(url); + Thrive.connectToServer = connectToServer; + + native function disconnectFromServer(); + Thrive.disconnectFromServer = disconnectFromServer; + }());