From 8b6bb4f42fb1c7f25e27582a3b07ea4ce710d4cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henri=20Hyyryl=C3=A4inen?= Date: Sat, 8 Dec 2018 14:17:02 +0200 Subject: [PATCH] The client can now somewhat connect to the server There are a lot of errors but now the client stays connected to the server without crashing or disconnecting after a few seconds --- .gitignore | 1 + SetupThrive.rb | 2 +- scripts/gui/main_menu.mjs | 29 ++- scripts/gui/thrive_gui.html | 24 +- scripts/microbe_stage/setup.as | 19 ++ src/ThriveGame.cpp | 181 ++++++++++++++- src/ThriveGame.h | 4 + src/microbe_stage/compound_cloud_system.cpp | 3 + src/microbe_stage/microbe_camera_system.cpp | 5 + src/server/ThriveServer.cpp | 12 +- src/server/ThriveServer.h | 6 +- src/server/main.cpp | 240 -------------------- src/server/thrive_server_net_handler.cpp | 7 + src/server/thrive_server_net_handler.h | 4 +- src/thrive_net_handler.cpp | 40 +++- src/thrive_net_handler.h | 7 + 16 files changed, 306 insertions(+), 278 deletions(-) delete mode 100644 src/server/main.cpp diff --git a/.gitignore b/.gitignore index 44f6dc40db4..0c3c42fd4a9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ assets/* /src/thrive_version.h /src/main.cpp /src/generated +/src/server/main.cpp # asset symlinks /Fonts diff --git a/SetupThrive.rb b/SetupThrive.rb index 7147d4b20e2..7b0eae61b52 100755 --- a/SetupThrive.rb +++ b/SetupThrive.rb @@ -78,7 +78,7 @@ def parseExtraArgs leviathan = Leviathan.new( # Use this if you always want the latest commit # version: "develop", - version: "5f3f3d1b3ef74b27f3ae7e1fb5f32a740dfcd813", + version: "e41a1b489733462337fd8fb914859c38d8bb9051", # Doesn't actually work, but leviathan doesn't install with sudo by # default, or install at all for that matter noInstallSudo: true diff --git a/scripts/gui/main_menu.mjs b/scripts/gui/main_menu.mjs index ee56233059a..d5239d3bba0 100644 --- a/scripts/gui/main_menu.mjs +++ b/scripts/gui/main_menu.mjs @@ -27,40 +27,47 @@ export function runMenuSetup(){ }, true); document.getElementById("extrasButton").addEventListener("click", (event) => { event.stopPropagation(); + common.playButtonPressSound(); $("#mainMenu").slideUp("fast", () => { $("#extrasMenu").slideDown("fast"); }); }, true); document.getElementById("backFromExtras").addEventListener("click", (event) => { event.stopPropagation(); + common.playButtonPressSound(); $("#extrasMenu").slideUp("fast", () => { $("#mainMenu").slideDown("fast"); }); }, true); document.getElementById("toMultiplayerProtoButton").addEventListener("click", (event) => { event.stopPropagation(); + common.playButtonPressSound(); $("#extrasMenu").slideUp("fast", () => { $("#serverConnectingMenu").slideDown("fast"); }); }, true); document.getElementById("backFromConnecting").addEventListener("click", (event) => { event.stopPropagation(); + common.playButtonPressSound(); $("#serverConnectingMenu").slideUp("fast", () => { $("#extrasMenu").slideDown("fast"); }); }, true); document.getElementById("backFromConnecting").addEventListener("click", (event) => { event.stopPropagation(); + common.playButtonPressSound(); $("#serverConnectingMenu").slideUp("fast", () => { $("#extrasMenu").slideDown("fast"); }); }, true); document.getElementById("connectToServerButton").addEventListener("click", (event) => { event.stopPropagation(); + common.playButtonPressSound(); connectToSelectedServerURL(); }, true); document.getElementById("disconnectFromServer").addEventListener("click", (event) => { event.stopPropagation(); + common.playButtonPressSound(); disconnectFromCurrentServer(); }, true); @@ -89,6 +96,10 @@ export function runMenuSetup(){ doExitToMenu(); }); + Leviathan.OnGeneric("MicrobeStageEnteredClient", () => { + switchToMicrobeHUD(); + }); + // Server status message display Leviathan.OnGeneric("ConnectStatusMessage", (event, vars) => { handleConnectionStatusEvent(vars); @@ -223,6 +234,8 @@ function disconnectFromCurrentServer(){ handleConnectionStatusEvent({show: false}); } + + // ThriveGame handles moving back to the menu GUI } function handleConnectionStatusEvent(event){ @@ -244,11 +257,6 @@ function onMicrobeIntroEnded(error){ menuAlreadySkipped = true; - if(jams){ - - jams.Pause(); - } - if(common.isInEngine()){ // Make sure no video is playing in case we did an immediate start @@ -261,6 +269,17 @@ function onMicrobeIntroEnded(error){ // Show the microbe GUI anyway for testing purposes } + switchToMicrobeHUD(); +} + +function switchToMicrobeHUD(){ + + // Stop menu music + if(jams){ + + jams.Pause(); + } + // Hide main menu // If this is ever restored this needs to be set to "flex" document.getElementById("topLevelMenuContainer").style.display = "none"; diff --git a/scripts/gui/thrive_gui.html b/scripts/gui/thrive_gui.html index d870efa87d0..55ddff6a00c 100644 --- a/scripts/gui/thrive_gui.html +++ b/scripts/gui/thrive_gui.html @@ -70,23 +70,23 @@ - - - JavaScript not loaded... + + +
diff --git a/scripts/microbe_stage/setup.as b/scripts/microbe_stage/setup.as index d6c312049e0..59810bff068 100644 --- a/scripts/microbe_stage/setup.as +++ b/scripts/microbe_stage/setup.as @@ -25,6 +25,12 @@ void setupScriptsForWorld_Server(CellStageWorld@ world) // setupSpawnSystem_Server(world); } +//! Server variant of setupScriptsForWorld +void setupScriptsForWorld_Client(CellStageWorld@ world) +{ + setupSystemsForWorld_Client(world); +} + // This function should be the entry point for all player initial-species generation // For now, it can go through the XML and instantiate all the species, but later this // would be all procedural. @@ -100,6 +106,19 @@ void setupSystemsForWorld_Server(CellStageWorld@ world) world.RegisterScriptSystem("MicrobeAISystem", MicrobeAISystem()); } +//! Client variant of setupSystemsForWorld +void setupSystemsForWorld_Client(CellStageWorld@ world) +{ + // Fail if compound registry is empty // + assert(SimulationParameters::compoundRegistry().getSize() > 0, + "Compound registry is empty"); + + world.RegisterScriptComponentType("MicrobeComponent", @MicrobeComponentFactory); + + world.RegisterScriptSystem("MicrobeSystem", MicrobeSystem()); + world.RegisterScriptSystem("MicrobeStageHudSystem", MicrobeStageHudSystem()); +} + //! This spawns the player void setupPlayer(CellStageWorld@ world) diff --git a/src/ThriveGame.cpp b/src/ThriveGame.cpp index f805e6ca072..65fad07f274 100644 --- a/src/ThriveGame.cpp +++ b/src/ThriveGame.cpp @@ -74,13 +74,16 @@ class ThriveGame::Implementation { { if(m_microbeBackgroundItem) { - m_cellStage->GetScene()->destroyItem(m_microbeBackgroundItem); + if(m_cellStage) + m_cellStage->GetScene()->destroyItem(m_microbeBackgroundItem); m_microbeBackgroundItem = nullptr; } if(m_microbeEditorBackgroundItem) { - m_microbeEditor->GetScene()->destroyItem( - m_microbeEditorBackgroundItem); + + if(m_microbeEditor) + m_microbeEditor->GetScene()->destroyItem( + m_microbeEditorBackgroundItem); m_microbeEditorBackgroundItem = nullptr; } } @@ -90,6 +93,9 @@ class ThriveGame::Implementation { { destroyBackgroundItem(); + LEVIATHAN_ASSERT( + m_cellStage, "Trying to create background item before world"); + m_microbeBackgroundItem = m_cellStage->GetScene()->createItem( m_microbeBackgroundMesh, Ogre::SCENE_STATIC); m_microbeBackgroundItem->setCastShadows(false); @@ -596,8 +602,16 @@ void Leviathan::Window* window1 = Engine::GetEngine()->GetWindowEntity(); window1->LinkObjects(nullptr); - // Clear the world - m_impl->m_cellStage->ClearEntities(); + // Disconnect + if(m_network->IsConnected()) { + + disconnectFromServer(true); + + } else { + + // Clear the world + m_impl->m_cellStage->ClearEntities(); + } // Get proper keys setup m_impl->m_menuKeyPresses->setEnabled(true); @@ -692,6 +706,20 @@ void LOG_INFO("Initiating disconnect from server"); m_network->DisconnectFromServer(reason); + // If we had managed to enter a game then needs to do this + if(m_impl->m_cellStage) { + + exitToMenuClicked(); + + m_impl->destroyBackgroundItem(); + + if(m_impl->m_cellStage) { + m_impl->m_cellStage->Release(); + } + + m_impl->m_cellStage.reset(); + } + if(!userInitiated) { Leviathan::GenericEvent::pointer event = new Leviathan::GenericEvent("ConnectStatusMessage"); @@ -717,6 +745,149 @@ void Engine::Get()->GetEventHandler()->CallEvent(event.detach()); } } +// ------------------------------------ // +void + ThriveGame::reportJoinedServerWorld(std::shared_ptr world) +{ + LEVIATHAN_ASSERT( + world->GetType() == static_cast(THRIVE_WORLD_TYPE::CELL_STAGE), + "unexpected world type"); + + // TODO: fix + if(m_impl->m_cellStage) { + + LOG_ERROR("double join happened, ignoring, TODO: FIX"); + return; + } + + LEVIATHAN_ASSERT(!m_impl->m_cellStage, "double join happened"); + + LOG_INFO("ThriveGame: client received world, moving to cell stage"); + + auto casted = std::dynamic_pointer_cast(world); + m_impl->m_cellStage = casted; + + // Hide the join status dialog + { + 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()); + } + + // Notify GUI to switch to the cell stage GUI + Engine::Get()->GetEventHandler()->CallEvent( + new Leviathan::GenericEvent("MicrobeStageEnteredClient")); + + Leviathan::Window* window1 = Engine::GetEngine()->GetWindowEntity(); + + window1->LinkObjects(m_impl->m_cellStage); + + // Set the right input handlers active // + m_impl->m_menuKeyPresses->setEnabled(false); + m_impl->m_cellStageKeys->setEnabled(true); + + // And switch the GUI mode to allow key presses through + auto layer = window1->GetGui()->GetLayerByIndex(0); + + // Allow running without GUI + if(layer) + layer->SetInputMode(Leviathan::GUI::INPUT_MODE::Gameplay); + + // Main camera that will be attached to the player + m_cellCamera = Leviathan::ObjectLoader::LoadCamera(*m_impl->m_cellStage, + Float3(0, 15, 0), + Ogre::Quaternion(Ogre::Degree(-90), Ogre::Vector3::UNIT_X)); + + // Link the camera to the camera control system + m_impl->m_cellStage->GetMicrobeCameraSystem().setCameraEntity(m_cellCamera); + + // TODO: attach a ligth to the camera + // -- Light + // local light = OgreLightComponent.new() + // light:setRange(200) + // entity:addComponent(light) + + m_impl->m_cellStage->SetCamera(m_cellCamera); + + // Setup compound clouds // + + // This is needed for the compound clouds to work in general + LEVIATHAN_ASSERT(SimulationParameters::compoundRegistry.getSize() > 0, + "compound registry is empty when creating cloud entities for them"); + + // Let the script do setup // + // This registers all the script defined systems to run and be + // available from the world + LEVIATHAN_ASSERT(getMicrobeScripts(), "microbe scripts not loaded"); + + LOG_INFO("Calling world setup script setupScriptsForWorld_Client"); + + ScriptRunningSetup setup; + setup.SetEntrypoint("setupScriptsForWorld_Client"); + + auto result = getMicrobeScripts()->ExecuteOnModule( + setup, false, m_impl->m_cellStage.get()); + + if(result.Result != SCRIPT_RUN_RESULT::Success) { + + LOG_ERROR( + "Failed to run script setup function: " + setup.Entryfunction); + MarkAsClosing(); + return; + } + + LOG_INFO("Finished calling setupScriptsForWorld"); + + // Set background plane // + // This is needed to be created here for biome.as to work correctly + // Also this is a manual object and with infinite extent as this isn't + // perspective projected in the shader + m_impl->m_backgroundRenderNode = + m_impl->m_cellStage->GetScene()->createSceneNode(Ogre::SCENE_STATIC); + + // This needs to be manually destroyed later + if(!m_impl->m_microbeBackgroundMesh) { + m_impl->m_microbeBackgroundMesh = + Leviathan::GeometryHelpers::CreateScreenSpaceQuad( + "CellStage_background", -1, -1, 2, 2); + + m_impl->m_microbeBackgroundSubMesh = + m_impl->m_microbeBackgroundMesh->getSubMesh(0); + + m_impl->m_microbeBackgroundSubMesh->setMaterialName("Background"); + } + // This also needs to be manually destroyed later. + if(!m_impl->m_microbeEditorBackgroundMesh) { + m_impl->m_microbeEditorBackgroundMesh = + Leviathan::GeometryHelpers::CreateScreenSpaceQuad( + "Editor_background", -1, -1, 2, 2); + + m_impl->m_microbeEditorBackgroundSubMesh = + m_impl->m_microbeEditorBackgroundMesh->getSubMesh(0); + + m_impl->m_microbeEditorBackgroundSubMesh->setMaterialName("Background"); + } + // Setup render queue for it + m_impl->m_cellStage->GetScene()->getRenderQueue()->setRenderQueueMode( + 1, Ogre::RenderQueue::FAST); + + // This now attaches the item as well (as long as the scene node is created) + // This makes it easier to manage the multiple backgrounds and reattaching + // them + if(!m_impl->m_microbeBackgroundItem) { + m_impl->createBackgroundItem(); + } + + // We handle spawning cells when the server tells us and we setup our + // control when we receive a notification of a direct control entity +} // ------------------------------------ // void diff --git a/src/ThriveGame.h b/src/ThriveGame.h index 05c88e7293d..89116c67f37 100644 --- a/src/ThriveGame.h +++ b/src/ThriveGame.h @@ -82,6 +82,10 @@ class ThriveGame : public Leviathan::ClientApplication, public ThriveCommon { disconnectFromServer(bool userInitiated, const std::string& reason = "Disconnect by user"); + //! \brief Called from the net handler when we have joined a world + void + reportJoinedServerWorld(std::shared_ptr world); + // ------------------------------------ // // Hooking into the engine, and overridden methods from base application // etc. diff --git a/src/microbe_stage/compound_cloud_system.cpp b/src/microbe_stage/compound_cloud_system.cpp index b200065693d..0bf3a822d4f 100644 --- a/src/microbe_stage/compound_cloud_system.cpp +++ b/src/microbe_stage/compound_cloud_system.cpp @@ -590,6 +590,9 @@ std::tuple void CompoundCloudSystem::Run(CellStageWorld& world) { + if(!world.GetNetworkSettings().IsAuthoritative) + return; + const int renderTime = Leviathan::TICKSPEED; auto playerEntity = ThriveGame::instance()->playerData().activeCreature(); diff --git a/src/microbe_stage/microbe_camera_system.cpp b/src/microbe_stage/microbe_camera_system.cpp index da3ccdd6dac..759604a5b21 100644 --- a/src/microbe_stage/microbe_camera_system.cpp +++ b/src/microbe_stage/microbe_camera_system.cpp @@ -39,6 +39,11 @@ void // Get the entity the camera should follow auto controlledEntity = ThriveGame::Get()->playerData().activeCreature(); + if(controlledEntity == NULL_OBJECT) { + // Nothing to control currently + return; + } + try { const auto& playerPos = diff --git a/src/server/ThriveServer.cpp b/src/server/ThriveServer.cpp index 9253e00db15..fa36dad6d0f 100644 --- a/src/server/ThriveServer.cpp +++ b/src/server/ThriveServer.cpp @@ -60,7 +60,7 @@ std::string } ThriveServer* - ThriveServer::Get() + ThriveServer::get() { return staticInstance; } @@ -160,6 +160,10 @@ void // LOG_ERROR("Failed to spawn player!"); // return; // } + + // Allow players joining + m_network->SetServerAllowPlayers(true); + m_network->SetServerStatus(Leviathan::SERVER_STATUS::Running); } // ------------------------------------ // CellStageWorld* @@ -167,6 +171,12 @@ CellStageWorld* { return m_impl->m_cellStage.get(); } + +std::shared_ptr + ThriveServer::getCellStageShared() +{ + return m_impl->m_cellStage; +} // ------------------------------------ // void ThriveServer::Tick(int mspassed) diff --git a/src/server/ThriveServer.h b/src/server/ThriveServer.h index 53f2531ff9a..65447cd7f1f 100644 --- a/src/server/ThriveServer.h +++ b/src/server/ThriveServer.h @@ -29,6 +29,10 @@ class ThriveServer : public Leviathan::ServerApplication, public ThriveCommon { CellStageWorld* getCellStage(); + std::shared_ptr + getCellStageShared(); + + // ------------------------------------ // // Hooking into the engine, and overridden methods from base application // etc. @@ -54,7 +58,7 @@ class ThriveServer : public Leviathan::ServerApplication, public ThriveCommon { KeyConfiguration* keyconfigobj); static ThriveServer* - Get(); + get(); bool InitLoadCustomScriptTypes(asIScriptEngine* engine) override; diff --git a/src/server/main.cpp b/src/server/main.cpp deleted file mode 100644 index f40d5a2a28f..00000000000 --- a/src/server/main.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include "thrive_version.h" -#include "ThriveServer.h" -#include "thrive_world_factory.h" - -#include "resource.h" - -#include "Define.h" -#include "Logger.h" -#include "GlobalCEFHandler.h" - -#ifdef _WIN32 -#include "include/cef_sandbox_win.h" -#endif - -#include -#include - - - -#define PROGRAMUSE_CUSTOMJS 0 -#if PROGRAMUSE_CUSTOMJS == 1 -// Define the actual macro // -#define LEVIATHAN_USES_CUSTOMJS -// Include required files // -#include "GlobalCEFHandler.h" -#include "GUI/GuiCEFApplication.h" -#endif - -#ifdef LEVIATHAN_USES_CUSTOMJS -// Include the header // -#include "generated/thrive_v8_extension.h" -#include "thrive_js_interface.h" -#endif - - -// Breakpad is used to detect and report crashes -#ifdef LEVIATHAN_USING_BREAKPAD -#ifdef __linux -#include "client/linux/handler/exception_handler.h" -#elif defined(_WIN32) -#include "client/windows/handler/exception_handler.h" -#else -#error no breakpad on platform -#endif -#endif //USE_BREAKPAD - -using namespace thrive; -// This is for easier logic with using standard classes instead of application specific -using namespace Leviathan; - -// Don't look at the mess ahead, just set the variables in your cmake file // - -#if LEVIATHAN_USING_BREAKPAD -#ifdef _WIN32 -#ifndef _DEBUG -bool DumpCallback(const wchar_t* dump_path, - const wchar_t* minidump_id, void* context, EXCEPTION_POINTERS* exinfo, - MDRawAssertionInfo* assertion, bool succeeded) -{ - - const string path = Convert::WstringToString(dump_path); - - printf("Dump path: %s\n", path.c_str()); - - return succeeded; -} -#endif //_DEBUG -#else -bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, - bool succeeded) -{ - printf("Dump path: %s\n", descriptor.path()); - return succeeded; -} -#endif -#endif //USE_BREAKPAD - -#ifdef _WIN32 -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, - int nCmdShow) -{ -#if defined(DEBUG) | defined(_DEBUG) - _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_DEBUG); -#endif - -#else -int main(int argcount, char* args[]){ -#endif - -#ifdef _WIN32 - int argcount = 1; - char* args[] = { lpCmdLine }; -#endif - - int Return = 0; - - // We need to manage the lifetime of an object // - std::shared_ptr KeepThisSafe; - - // This needs to create the sandbox as otherwise this doesn't work -#ifdef CEF_ENABLE_SANDBOX - // Manage the life span of the sandbox information object. This is necessary - // for sandbox support on Windows. See cef_sandbox_win.h for complete details. - CefScopedSandboxInfo sandbox = CefScopedSandboxInfo(); -#endif - - - // The default CEF handling needs to be the first thing in the program // - if(Leviathan::GlobalCEFHandler::CEFFirstCheckChildProcess(argcount, args, Return, - KeepThisSafe, "ThriveServer" - #ifdef _WIN32 - #ifdef CEF_ENABLE_SANDBOX - , sandbox - #endif - , hInstance - #endif - )) - { - // This was a child process, end it now // - return Return; - } - // This is the main process, continue normally // - -#ifndef _WIN32 - // We need to skip the program name - args += 1; - --argcount; -#endif // _WIN32 - -#ifdef _WIN32 - HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); - - if(SUCCEEDED(CoInitialize(NULL))){ -#else - -#endif - -#if LEVIATHAN_USING_BREAKPAD - // Crash handler // -#ifdef _WIN32 -#ifndef _DEBUG - google_breakpad::ExceptionHandler ExceptionHandler(L"C://tmp", NULL, DumpCallback, NULL, - google_breakpad::ExceptionHandler::HANDLER_ALL, - (MINIDUMP_TYPE)(MiniDumpNormal & MiniDumpWithThreadInfo), - (const wchar_t*)nullptr, NULL); - -#endif //_DEBUG -#else - google_breakpad::MinidumpDescriptor descriptor("/tmp"); - - google_breakpad::ExceptionHandler ExceptionHandler(descriptor, NULL, DumpCallback, NULL, - true, -1); -#endif -#endif //USE_BREAKPAD - - // Logger. This is here to make logging shutdown errors etc. possible // - Logger mainLog("ThriveServer" + std::string("Log.txt")); - - // World creator object // - ThriveWorldFactory worldFactory; - - // Create program object // - ThriveServer app; - - std::unique_ptr ProgramDefinition(AppDef::GenerateAppdefine( - "./EngineConf.conf", "./ThriveServer.conf", "./ThriveKeybindings.conf", - &ThriveServer::CheckGameConfigurationVariables, &ThriveServer::CheckGameKeyConfigVariables)); - - // Fail if no definition could be created // - if(!ProgramDefinition){ - - std::cout << "FATAL: failed to create AppDefine" << std::endl; - return 2; - } - - - // customize values // -#ifdef _WIN32 - ProgramDefinition->SetHInstance(hInstance); -#endif - ProgramDefinition->SetMasterServerParameters(MasterServerInformation()). - SetApplicationIdentification( - "Thrive server version " GAME_VERSIONS, "Thrive", - "GAME_VERSIONS"); - - // Create window last // - ProgramDefinition->StoreWindowDetails(ThriveServer::GenerateWindowTitle(), true, -#ifdef _WIN32 - LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)), -#endif - &app); - - if(!app.PassCommandLine(argcount, args)){ - - std::cout << "Error: Invalid Command Line arguments. Shutting down" << std::endl; - return 3; - } - - // Register our custom JS object if we are using one // -#ifdef LEVIATHAN_USES_CUSTOMJS - Leviathan::GlobalCEFHandler::RegisterCustomJavaScriptQueryHandler( - std::make_shared()); - - // Register the custom file // - Leviathan::GlobalCEFHandler::RegisterCustomExtension( - std::make_shared( - "ThriveJSInterface", thrive_v8_extensionStr, &makeThriveJSHandler, - std::make_shared())); - -#endif //LEVIATHAN_USES_CUSTOMJS - - - if(app.Initialize(ProgramDefinition.get())){ - - // this is where the game should customize the engine // - app.CustomizeEnginePostLoad(); - - LOG_INFO("Engine successfully initialized"); - Return = app.RunMessageLoop(); - } else { - LOG_ERROR("App init failed, closing"); - app.ForceRelease(); - Return = 5; - } -#ifdef _WIN32 - } - //_CrtDumpMemoryLeaks(); - CoUninitialize(); -#endif - - // The CEF application will go out of scope after this // - KeepThisSafe.reset(); - - // This needs to be called before quitting // - Leviathan::GlobalCEFHandler::CEFLastThingInProgram(); - - // Sandbox will go out of scope after this - - return Return; -} diff --git a/src/server/thrive_server_net_handler.cpp b/src/server/thrive_server_net_handler.cpp index 4da59b3ae8a..c19dd6216b8 100644 --- a/src/server/thrive_server_net_handler.cpp +++ b/src/server/thrive_server_net_handler.cpp @@ -1,6 +1,8 @@ // ------------------------------------ // #include "thrive_server_net_handler.h" +#include "ThriveServer.h" +#include "generated/cell_stage_world.h" using namespace thrive; // ------------------------------------ // ThriveServerNetHandler::ThriveServerNetHandler() : @@ -11,3 +13,8 @@ ThriveServerNetHandler::ThriveServerNetHandler() : ThriveServerNetHandler::~ThriveServerNetHandler() {} // ------------------------------------ // +std::shared_ptr + ThriveServerNetHandler::_GetWorldForJoinTarget(const std::string& options) +{ + return ThriveServer::get()->getCellStageShared(); +} diff --git a/src/server/thrive_server_net_handler.h b/src/server/thrive_server_net_handler.h index 7403a0f2859..221e025ed1a 100644 --- a/src/server/thrive_server_net_handler.h +++ b/src/server/thrive_server_net_handler.h @@ -15,8 +15,8 @@ class ThriveServerNetHandler : public Leviathan::NetworkServerInterface { ThriveServerNetHandler(); virtual ~ThriveServerNetHandler(); - - protected: + std::shared_ptr + _GetWorldForJoinTarget(const std::string& options) override; }; } // namespace thrive diff --git a/src/thrive_net_handler.cpp b/src/thrive_net_handler.cpp index 008811bbcc9..7cc454ea818 100644 --- a/src/thrive_net_handler.cpp +++ b/src/thrive_net_handler.cpp @@ -1,10 +1,12 @@ // ------------------------------------ // #include "thrive_net_handler.h" -#include "GUI/GuiManager.h" +#include "ThriveGame.h" -#include "Engine.h" -#include "Events/EventHandler.h" +#include +#include +#include +#include using namespace thrive; // ------------------------------------ // @@ -15,23 +17,39 @@ ThriveNetHandler::~ThriveNetHandler() {} void ThriveNetHandler::_OnProperlyConnected() { - LOG_WRITE("TODO: ask to join cell stage world"); + DoJoinDefaultWorld(); } // ------------------------------------ // void ThriveNetHandler::_OnNewConnectionStatusMessage(const std::string& message) { - Engine::Get()->GetEventHandler()->CallEvent(new Leviathan::GenericEvent( - "ConnectStatusMessage", - Leviathan::NamedVars(std::shared_ptr( - new NamedVariableList("Message", new VariableBlock(message)))))); + 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(message))); + + Engine::Get()->GetEventHandler()->CallEvent(event.detach()); } // ------------------------------------ // void ThriveNetHandler::_OnDisconnectFromServer(const std::string& reasonstring, bool donebyus) +{} +// ------------------------------------ // +std::shared_ptr + ThriveNetHandler::GetPhysicsMaterialsForReceivedWorld(int32_t worldtype, + const std::string& extraoptions) +{ + return ThriveGame::Get()->createPhysicsMaterials(); +} + +void + ThriveNetHandler::_OnWorldJoined(std::shared_ptr world) { - // Enable the connection screen to display this message // - // Engine::Get()->GetWindowEntity()->GetGUI()->SetCollectionState("ConnectionScreen", - // true); + ThriveGame::Get()->reportJoinedServerWorld(world); } diff --git a/src/thrive_net_handler.h b/src/thrive_net_handler.h index 24a1a999332..ef66b6d579b 100644 --- a/src/thrive_net_handler.h +++ b/src/thrive_net_handler.h @@ -28,5 +28,12 @@ class ThriveNetHandler : public Leviathan::NetworkClientInterface { void _OnDisconnectFromServer(const std::string& reasonstring, bool donebyus) override; + + std::shared_ptr + GetPhysicsMaterialsForReceivedWorld(int32_t worldtype, + const std::string& extraoptions) override; + + void + _OnWorldJoined(std::shared_ptr world) override; }; } // namespace thrive