diff --git a/CMakeLists.txt b/CMakeLists.txt index 41cb379b..5a263810 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,8 +15,6 @@ endif() if (EMSCRIPTEN) add_compile_options(-pthread) add_link_options(-sUSE_WEBGL2=1 -sMIN_WEBGL_VERSION=2 -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=2gb -sUSE_PTHREADS=1 -sPROXY_TO_PTHREAD=1 -sOFFSCREENCANVAS_SUPPORT=1 -sPTHREAD_POOL_SIZE_STRICT=0 -sFORCE_FILESYSTEM=1 -sWASMFS=1 -sEXIT_RUNTIME=1) - add_link_options("-sEXPORTED_FUNCTIONS=[\"_main\",\"_mp_set_walk_animation\",\"_mp_set_idle_animation\",\"_mp_trigger_emote\",\"_mp_get_player_count\"]") - add_link_options("-sEXPORTED_RUNTIME_METHODS=[\"ccall\",\"cwrap\"]") set(SDL_PTHREADS ON CACHE BOOL "Enable SDL pthreads" FORCE) endif() @@ -595,6 +593,11 @@ if (ISLE_BUILD_APP) ISLE/emscripten/messagebox.cpp ISLE/emscripten/window.cpp ) + if(ISLE_EXTENSIONS) + target_sources(isle PRIVATE + extensions/src/multiplayer/wasm_exports.cpp + ) + endif() target_compile_definitions(isle PRIVATE "ISLE_EMSCRIPTEN_HOST=\"${ISLE_EMSCRIPTEN_HOST}\"") set_property(TARGET isle PROPERTY SUFFIX ".html") endif() diff --git a/extensions/include/extensions/multiplayer/networkmanager.h b/extensions/include/extensions/multiplayer/networkmanager.h index b2bf5989..adcf41f4 100644 --- a/extensions/include/extensions/multiplayer/networkmanager.h +++ b/extensions/include/extensions/multiplayer/networkmanager.h @@ -44,7 +44,6 @@ class NetworkManager : public MxCore { void SetWalkAnimation(uint8_t p_index); void SetIdleAnimation(uint8_t p_index); void SendEmote(uint8_t p_emoteId); - int GetPlayerCount() const; void OnWorldEnabled(LegoWorld* p_world); void OnWorldDisabled(LegoWorld* p_world); @@ -71,6 +70,7 @@ class NetworkManager : public MxCore { void RemoveRemotePlayer(uint32_t p_peerId); void RemoveAllRemotePlayers(); + void NotifyPlayerCountChanged(); int8_t DetectLocalVehicleType(); // Serialize and send a fixed-size message via the transport diff --git a/extensions/src/multiplayer.cpp b/extensions/src/multiplayer.cpp index a05442f3..91d6adc4 100644 --- a/extensions/src/multiplayer.cpp +++ b/extensions/src/multiplayer.cpp @@ -125,42 +125,3 @@ bool Extensions::IsMultiplayerRejected() { return Extension::Call(CheckRejected).value_or(FALSE); } - -#ifdef __EMSCRIPTEN__ -extern "C" { - -EMSCRIPTEN_KEEPALIVE void mp_set_walk_animation(int index) -{ - Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); - if (mgr) { - mgr->SetWalkAnimation(static_cast(index)); - } -} - -EMSCRIPTEN_KEEPALIVE void mp_set_idle_animation(int index) -{ - Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); - if (mgr) { - mgr->SetIdleAnimation(static_cast(index)); - } -} - -EMSCRIPTEN_KEEPALIVE void mp_trigger_emote(int index) -{ - Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); - if (mgr) { - mgr->SendEmote(static_cast(index)); - } -} - -EMSCRIPTEN_KEEPALIVE int mp_get_player_count() -{ - Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); - if (mgr) { - return mgr->GetPlayerCount(); - } - return 0; -} - -} // extern "C" -#endif diff --git a/extensions/src/multiplayer/networkmanager.cpp b/extensions/src/multiplayer/networkmanager.cpp index 51bf3ae3..dd8825c0 100644 --- a/extensions/src/multiplayer/networkmanager.cpp +++ b/extensions/src/multiplayer/networkmanager.cpp @@ -11,6 +11,9 @@ #include #include #include +#ifdef __EMSCRIPTEN__ +#include +#endif using namespace Multiplayer; @@ -145,6 +148,8 @@ void NetworkManager::OnWorldEnabled(LegoWorld* p_world) } } } + + NotifyPlayerCountChanged(); } } @@ -160,6 +165,8 @@ void NetworkManager::OnWorldDisabled(LegoWorld* p_world) for (auto& [peerId, player] : m_remotePlayers) { player->SetVisible(false); } + + NotifyPlayerCountChanged(); } } @@ -338,6 +345,7 @@ void NetworkManager::HandleJoin(const PlayerJoinMsg& p_msg) } CreateAndSpawnPlayer(peerId, p_msg.actorId); + NotifyPlayerCountChanged(); } void NetworkManager::HandleLeave(const PlayerLeaveMsg& p_msg) @@ -356,6 +364,7 @@ void NetworkManager::HandleState(const PlayerStateMsg& p_msg) } CreateAndSpawnPlayer(peerId, p_msg.actorId); + NotifyPlayerCountChanged(); it = m_remotePlayers.find(peerId); } @@ -367,12 +376,20 @@ void NetworkManager::HandleState(const PlayerStateMsg& p_msg) it = m_remotePlayers.find(peerId); } + int8_t oldWorldId = it->second->GetWorldId(); + it->second->UpdateFromNetwork(p_msg); bool bothInIsle = m_inIsleWorld && (p_msg.worldId == (int8_t) LegoOmni::e_act1); if (it->second->IsSpawned()) { it->second->SetVisible(bothInIsle); } + + bool wasInIsle = (oldWorldId == (int8_t) LegoOmni::e_act1); + bool nowInIsle = (p_msg.worldId == (int8_t) LegoOmni::e_act1); + if (m_inIsleWorld && wasInIsle != nowInIsle) { + NotifyPlayerCountChanged(); + } } void NetworkManager::HandleHostAssign(const HostAssignMsg& p_msg) @@ -413,12 +430,6 @@ void NetworkManager::SendEmote(uint8_t p_emoteId) SendMessage(msg); } -int NetworkManager::GetPlayerCount() const -{ - // +1 for the local player - return static_cast(m_remotePlayers.size()) + 1; -} - void NetworkManager::HandleEmote(const EmoteMsg& p_msg) { uint32_t peerId = p_msg.header.peerId; @@ -434,6 +445,7 @@ void NetworkManager::RemoveRemotePlayer(uint32_t p_peerId) if (it != m_remotePlayers.end()) { it->second->Despawn(); m_remotePlayers.erase(it); + NotifyPlayerCountChanged(); } } @@ -443,6 +455,32 @@ void NetworkManager::RemoveAllRemotePlayers() player->Despawn(); } m_remotePlayers.clear(); + NotifyPlayerCountChanged(); +} + +void NetworkManager::NotifyPlayerCountChanged() +{ +#ifdef __EMSCRIPTEN__ + int count = -1; + if (m_inIsleWorld) { + count = 1; // local player + for (auto& [peerId, player] : m_remotePlayers) { + if (player->GetWorldId() == (int8_t) LegoOmni::e_act1) { + count++; + } + } + } + // clang-format off + MAIN_THREAD_EM_ASM({ + var canvas = Module.canvas; + if (canvas) { + canvas.dispatchEvent(new CustomEvent('playerCountChanged', { + detail: { count: $0 < 0 ? null : $0 } + })); + } + }, count); + // clang-format on +#endif } int8_t NetworkManager::DetectLocalVehicleType() diff --git a/extensions/src/multiplayer/wasm_exports.cpp b/extensions/src/multiplayer/wasm_exports.cpp new file mode 100644 index 00000000..f3366c28 --- /dev/null +++ b/extensions/src/multiplayer/wasm_exports.cpp @@ -0,0 +1,38 @@ +#ifdef __EMSCRIPTEN__ + +#include "extensions/multiplayer.h" +#include "extensions/multiplayer/networkmanager.h" + +#include + +using namespace Extensions; + +extern "C" { + +EMSCRIPTEN_KEEPALIVE void mp_set_walk_animation(int index) +{ + Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); + if (mgr) { + mgr->SetWalkAnimation(static_cast(index)); + } +} + +EMSCRIPTEN_KEEPALIVE void mp_set_idle_animation(int index) +{ + Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); + if (mgr) { + mgr->SetIdleAnimation(static_cast(index)); + } +} + +EMSCRIPTEN_KEEPALIVE void mp_trigger_emote(int index) +{ + Multiplayer::NetworkManager* mgr = MultiplayerExt::GetNetworkManager(); + if (mgr) { + mgr->SendEmote(static_cast(index)); + } +} + +} // extern "C" + +#endif