diff --git a/.github/actions/pr_base/action.yml b/.github/actions/pr_base/action.yml index 61d8c111ef..90e3294764 100644 --- a/.github/actions/pr_base/action.yml +++ b/.github/actions/pr_base/action.yml @@ -24,6 +24,10 @@ inputs: SKYMP5_PATCHES_PAT: description: "PAT for skymp5-patches repository" required: true + EMSCRIPTEN: + description: "Set to true if building for Emscripten" + required: false + default: "false" runs: using: composite steps: @@ -130,17 +134,37 @@ runs: # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type # Outputs profiling data in Google Trace Format, which can be parsed by the about:tracing tab of Google Chrome or using a plugin for a tool like Trace Compass. run: | + if ('${{ inputs.EMSCRIPTEN }}' -eq 'true') { + git clone --depth 1 https://github.com/emscripten-core/emsdk.git + cd emsdk + ./emsdk install 3.1.64 + ./emsdk activate 3.1.64 + . .\emsdk_env.ps1 + cd .. + } + + $cmake_command = if ('${{ inputs.EMSCRIPTEN }}' -eq 'true') { "emcmake cmake" } else { "cmake" } + $cppcov_path_arg = if ($env:RUNNER_OS -eq 'Windows') { '-DCPPCOV_PATH="C:\Program Files\OpenCppCoverage"' } else { '-DCPPCOV_PATH=OFF' } $vcpkg_root_arg = if ($env:RUNNER_OS -eq 'Windows') { '-DVCPKG_ROOT=C:/vcpkg' } else { '-DVCPKG_ROOT="${{github.workspace}}/vcpkg"' } - cmake -B ${{github.workspace}}/build ` - $vcpkg_root_arg ` - -DUNIT_DATA_DIR="skyrim_data_files" ` - -DPREPARE_NEXUS_ARCHIVES=ON ` - -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} ` - -DSKYRIM_SE=${{ inputs.SKYRIM_SE_FLAG }} ` - $cppcov_path_arg ` - --profiling-output cmake-profiling-output ` - --profiling-format google-trace + $vcpkg_chainload_toolchain_arg = if ('${{ inputs.EMSCRIPTEN }}' -eq 'true') { '-DVCPKG_CHAINLOAD_TOOLCHAIN_FILE="${{github.workspace}}/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake"' } else { '' } + $vcpkg_triplet_arg = if ('${{ inputs.EMSCRIPTEN }}' -eq 'true') { '-DVCPKG_TARGET_TRIPLET=wasm32-emscripten' } else { '' } + $prepare_nexus_archives_arg = if ('${{ inputs.SP_NEXUS_ARTIFACT_NAME}}' -eq 'nope') { '-DPREPARE_NEXUS_ARCHIVES=OFF' } else { '-DPREPARE_NEXUS_ARCHIVES=ON' } + + $cmake_command_full = "$cmake_command " + $cmake_command_full += "-B ${{github.workspace}}/build " + $cmake_command_full += "$vcpkg_chainload_toolchain_arg " + $cmake_command_full += "$vcpkg_triplet_arg " + $cmake_command_full += "$vcpkg_root_arg " + $cmake_command_full += "-DUNIT_DATA_DIR=skyrim_data_files " + $cmake_command_full += "$prepare_nexus_archives_arg " + $cmake_command_full += "-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} " + $cmake_command_full += "-DSKYRIM_SE=${{ inputs.SKYRIM_SE_FLAG }} " + $cmake_command_full += "$cppcov_path_arg " + $cmake_command_full += "--profiling-output cmake-profiling-output " + $cmake_command_full += "--profiling-format google-trace" + + Invoke-Expression $cmake_command_full shell: powershell - name: Upload vcpkg failure logs @@ -148,7 +172,8 @@ runs: uses: actions/upload-artifact@v4 with: name: install-x64-linux-dbg-out.log - path: C:\vcpkg\buildtrees\spdlog\install-x64-windows-sp-dbg-out.log + #path: C:\vcpkg\buildtrees\spdlog\install-x64-windows-sp-dbg-out.log + path: /Users/runner/work/skymp/skymp/vcpkg/buildtrees/slikenet/install-wasm32-emscripten-dbg-out.log - uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/pr-emscripten.yml b/.github/workflows/pr-emscripten.yml new file mode 100644 index 0000000000..2039c68fdc --- /dev/null +++ b/.github/workflows/pr-emscripten.yml @@ -0,0 +1,42 @@ +name: PR Emscripten + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + schedule: + - cron: '0 0 * * *' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) + BUILD_TYPE: Release + VCPKG_BINARY_SOURCES: 'clear;x-gha,readwrite' + VCPKG_FEATURE_FLAGS: 'manifests' + +jobs: + build: + # MacOS has powershell + runs-on: macos-12 + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 1 + submodules: 'true' + + - name: Setup Emscripten environment + uses: actions/setup-python@v4 + with: + python-version: '3.x' + + - uses: ./.github/actions/pr_base + with: + DESCRIPTION: 'Emscripten Build' + DIST_ARTIFACT_NAME: dist-emscripten + SERVER_DIST_ARTIFACT_NAME: server-dist-emscripten + SKYMP5_PATCHES_PAT: ${{ secrets.SKYMP5_PATCHES_PAT }} + EMSCRIPTEN: true diff --git a/1js/JsEngine.h b/1js/JsEngine.h index 1b1bbe98f8..052a09e2c0 100644 --- a/1js/JsEngine.h +++ b/1js/JsEngine.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fe525e4b2..8478d8dbe0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,12 +4,14 @@ if(POLICY 0115) cmake_policy(SET CMP0115 NEW) endif() -if(WIN32) - set(VCPKG_TARGET_TRIPLET "x64-windows-sp") -elseif(APPLE) - set(VCPKG_TARGET_TRIPLET "x64-osx") -else() - set(VCPKG_TARGET_TRIPLET "x64-linux") +if("${VCPKG_TARGET_TRIPLET}" STREQUAL "") + if(WIN32) + set(VCPKG_TARGET_TRIPLET "x64-windows-sp") + elseif(APPLE) + set(VCPKG_TARGET_TRIPLET "x64-osx") + else() + set(VCPKG_TARGET_TRIPLET "x64-linux") + endif() endif() set(VCPKG_OVERLAY_TRIPLETS "${CMAKE_CURRENT_LIST_DIR}/overlay_triplets") @@ -88,6 +90,10 @@ message(STATUS INSTALL_CLIENT_DIST=${INSTALL_CLIENT_DIST}) message(STATUS BUILD_GAMEMODE=${BUILD_GAMEMODE}) message(STATUS OFFLINE_MODE=${OFFLINE_MODE}) +if(PREPARE_NEXUS_ARCHIVES AND EMSCRIPTEN) + message(FATAL_ERROR "PREPARE_NEXUS_ARCHIVES is not supported on Emscripten") +endif() + # Note that SkyrimPlatform performance drops significantly with JS_ENGINE_TRACING_ENABLED set to true. if(JS_ENGINE_TRACING_ENABLED) @@ -145,7 +151,8 @@ add_subdirectory(skymp5-functions-lib) add_subdirectory(skymp5-scripts) add_subdirectory(skymp5-server) -if(BUILD_UNIT_TESTS) +# TODO: enable for Emscripten once stabilize +if(BUILD_UNIT_TESTS AND NOT EMSCRIPTEN) add_subdirectory(unit) endif() diff --git a/cmake/run_test_unit.cmake b/cmake/run_test_unit.cmake index a5e847e455..3b0092aeda 100644 --- a/cmake/run_test_unit.cmake +++ b/cmake/run_test_unit.cmake @@ -13,11 +13,21 @@ if(temp_coverage) file(REMOVE ${temp_coverage}) endif() -execute_process(COMMAND ${EXE_PATH} - RESULT_VARIABLE res - OUTPUT_VARIABLE out - WORKING_DIRECTORY "${UNIT_WORKING_DIRECTORY}" -) +# Emscripten support +if("${EXE_PATH}" MATCHES ".*\.js") + execute_process(COMMAND node ${EXE_PATH} + RESULT_VARIABLE res + OUTPUT_VARIABLE out + WORKING_DIRECTORY "${UNIT_WORKING_DIRECTORY}" + ) +else() + execute_process(COMMAND ${EXE_PATH} + RESULT_VARIABLE res + OUTPUT_VARIABLE out + WORKING_DIRECTORY "${UNIT_WORKING_DIRECTORY}" + ) +endif() + message("${out}") if(NOT "${res}" STREQUAL "0") diff --git a/libespm/CMakeLists.txt b/libespm/CMakeLists.txt index 5dd4724cd5..f04bec1f5e 100644 --- a/libespm/CMakeLists.txt +++ b/libespm/CMakeLists.txt @@ -10,8 +10,4 @@ apply_default_settings(TARGETS espm) add_library(libespm ALIAS espm) -find_path(SPARSEPP_INCLUDE_DIR NAMES spp.h PATH_SUFFIXES sparsepp) -get_filename_component(SPARSEPP_INCLUDE_DIR ${SPARSEPP_INCLUDE_DIR} DIRECTORY) -target_include_directories(espm PUBLIC ${SPARSEPP_INCLUDE_DIR}) - target_link_libraries(espm PUBLIC viet) diff --git a/libespm/include/libespm/CompressedFieldsCache.h b/libespm/include/libespm/CompressedFieldsCache.h index 14bff78bfb..ea51a54ded 100644 --- a/libespm/include/libespm/CompressedFieldsCache.h +++ b/libespm/include/libespm/CompressedFieldsCache.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #pragma pack(push, 1) @@ -20,7 +20,7 @@ class CompressedFieldsCache std::shared_ptr> decompressedFieldsHolder; }; - spp::sparse_hash_map data; + std::unordered_map data; }; } diff --git a/libespm/include/libespm/DataTypes.h b/libespm/include/libespm/DataTypes.h index 1cc577ed5b..4b5913f450 100644 --- a/libespm/include/libespm/DataTypes.h +++ b/libespm/include/libespm/DataTypes.h @@ -1,14 +1,16 @@ #pragma once +#include +#include namespace espm { -using RecordFlagsType = std::uint32_t; +using RecordFlagsType = uint32_t; /// /// A ulong used to identify a data object. May refer to a data object from a /// mod or new object created in-game. /// -using formId = std::uint32_t; +using formId = uint32_t; /// /// 'Localized string', a ulong that is used as an index to look up string data @@ -16,7 +18,7 @@ using formId = std::uint32_t; /// the TES4 record indicates if the file is localized or not. If not, all /// lstrings are zstrings. /// -using lstring = std::uint32_t; +using lstring = uint32_t; /// /// Zero terminated string diff --git a/libespm/include/libespm/RecordHeader.h b/libespm/include/libespm/RecordHeader.h index 780e649ac7..939c41d99c 100644 --- a/libespm/include/libespm/RecordHeader.h +++ b/libespm/include/libespm/RecordHeader.h @@ -2,6 +2,7 @@ #include "CompressedFieldsCache.h" #include "DataTypes.h" #include "Type.h" +#include // memcmp #pragma pack(push, 1) diff --git a/libespm/src/Browser.cpp b/libespm/src/Browser.cpp index 52b8e73e7a..88bb82654a 100644 --- a/libespm/src/Browser.cpp +++ b/libespm/src/Browser.cpp @@ -16,7 +16,8 @@ #include "libespm/WRLD.h" #include #include -#include +#include +#include #include namespace espm { @@ -31,13 +32,13 @@ struct Browser::Impl size_t pos = 0; uint32_t fiDataSizeOverride = 0; - spp::sparse_hash_map recById; - spp::sparse_hash_map> navmeshes; - spp::sparse_hash_map> + std::unordered_map recById; + std::unordered_map> navmeshes; + std::unordered_map> cellOrWorldChildren; - spp::sparse_hash_map + std::unordered_map groupDataByGroupPtr; - spp::sparse_hash_map + std::unordered_map groupStackByRecordPtr; std::vector objectReferences; std::vector constructibleObjects; diff --git a/libespm/src/CombineBrowser.cpp b/libespm/src/CombineBrowser.cpp index 757ddf8645..7c418b8304 100644 --- a/libespm/src/CombineBrowser.cpp +++ b/libespm/src/CombineBrowser.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace espm { @@ -91,7 +92,7 @@ std::vector CombineBrowser::GetDistinctRecordsByType( return {}; } - spp::sparse_hash_set formSet; + std::unordered_set formSet; std::vector result; for (size_t i = pImpl->numSources - 1; i != static_cast(-1); --i) { const auto& records = pImpl->sources[i].br->GetRecordsByType(type); diff --git a/libespm/src/Combiner.cpp b/libespm/src/Combiner.cpp index c24b62cdb0..ccbafa7ab8 100644 --- a/libespm/src/Combiner.cpp +++ b/libespm/src/Combiner.cpp @@ -6,7 +6,6 @@ #include "libespm/espm.h" #include #include -#include #include namespace espm { diff --git a/libespm/src/CompressedFieldsCache.cpp b/libespm/src/CompressedFieldsCache.cpp index 0df4bd9214..25fa792bcf 100644 --- a/libespm/src/CompressedFieldsCache.cpp +++ b/libespm/src/CompressedFieldsCache.cpp @@ -1,7 +1,6 @@ #include "libespm/CompressedFieldsCache.h" #include "libespm/RecordHeader.h" #include -#include #include namespace espm { diff --git a/overlay_ports/slikenet/fix-emscripten.patch b/overlay_ports/slikenet/fix-emscripten.patch new file mode 100644 index 0000000000..2a200a9bf8 --- /dev/null +++ b/overlay_ports/slikenet/fix-emscripten.patch @@ -0,0 +1,247 @@ +diff --git a/Source/include/slikenet/Export.h b/Source/include/slikenet/Export.h +index 4487ef7e0..4bcd868f3 100644 +--- a/Source/include/slikenet/Export.h ++++ b/Source/include/slikenet/Export.h +@@ -15,7 +15,7 @@ + + #include "defines.h" + +-#if defined(_WIN32) && !(defined(__GNUC__) || defined(__GCCXML__)) && !defined(_RAKNET_LIB) && defined(_RAKNET_DLL) ++#if defined(_WIN32) && !(defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__GCCXML__)) && !defined(_RAKNET_LIB) && defined(_RAKNET_DLL) + #define RAK_DLL_EXPORT __declspec(dllexport) + #else + #define RAK_DLL_EXPORT +diff --git a/Source/include/slikenet/LinuxStrings.h b/Source/include/slikenet/LinuxStrings.h +index c0fd72bee..53e02c834 100644 +--- a/Source/include/slikenet/LinuxStrings.h ++++ b/Source/include/slikenet/LinuxStrings.h +@@ -23,7 +23,7 @@ + int _strnicmp(const char* s1, const char* s2, size_t n); + char *_strlwr(char * str ); + #else +- #if (defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__) ) && !defined(_WIN32) ++ #if (defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__) ) && !defined(_WIN32) + #ifndef _stricmp + int _stricmp(const char* s1, const char* s2); + #endif +diff --git a/Source/include/slikenet/NativeTypes.h b/Source/include/slikenet/NativeTypes.h +index 0b1305e31..1a1112d63 100644 +--- a/Source/include/slikenet/NativeTypes.h ++++ b/Source/include/slikenet/NativeTypes.h +@@ -16,7 +16,7 @@ + #ifndef __NATIVE_TYPES_H + #define __NATIVE_TYPES_H + +-#if defined(__GNUC__) || defined(__GCCXML__) || defined(__SNC__) || defined(__S3E__) ++#if defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__GCCXML__) || defined(__SNC__) || defined(__S3E__) + #include + #elif !defined(_STDINT_H) && !defined(_SN_STDINT_H) && !defined(_SYS_STDINT_H_) && !defined(_STDINT) && !defined(_MACHTYPES_H_) && !defined(_STDINT_H_) + typedef unsigned char uint8_t; +diff --git a/Source/include/slikenet/_FindFirst.h b/Source/include/slikenet/_FindFirst.h +index 74f5d8aa0..8906063aa 100644 +--- a/Source/include/slikenet/_FindFirst.h ++++ b/Source/include/slikenet/_FindFirst.h +@@ -16,7 +16,7 @@ + #ifndef GCC_FINDFIRST_H + #define GCC_FINDFIRST_H + +-#if (defined(__GNUC__) || defined(__ARMCC_VERSION) || defined(__GCCXML__) || defined(__S3E__) ) && !defined(__WIN32) ++#if (defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__ARMCC_VERSION) || defined(__GCCXML__) || defined(__S3E__) ) && !defined(__WIN32) + + #include + +diff --git a/Source/include/slikenet/linux_adapter.h b/Source/include/slikenet/linux_adapter.h +index b8a228f2d..1b578d9e5 100644 +--- a/Source/include/slikenet/linux_adapter.h ++++ b/Source/include/slikenet/linux_adapter.h +@@ -9,7 +9,7 @@ + */ + #pragma once + +-#ifdef __linux__ ++#if defined(__linux__) || defined(__EMSCRIPTEN__) + #define _TRUNCATE ((size_t)-1) + typedef int errno_t; + +diff --git a/Source/include/slikenet/socket2.h b/Source/include/slikenet/socket2.h +index fde1ee471..52514512b 100644 +--- a/Source/include/slikenet/socket2.h ++++ b/Source/include/slikenet/socket2.h +@@ -354,7 +354,7 @@ class RNS2_Berkley : public IRNS2_Berkley + + + +-#if defined(_WIN32) || defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__) ++#if defined(_WIN32) || defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__) + class RNS2_Windows_Linux_360 + { + public: +diff --git a/Source/src/FileList.cpp b/Source/src/FileList.cpp +index 514d2aa88..77c6bf12a 100644 +--- a/Source/src/FileList.cpp ++++ b/Source/src/FileList.cpp +@@ -25,7 +25,7 @@ + #include + + +-#elif !defined ( __APPLE__ ) && !defined ( __APPLE_CC__ ) && !defined ( __PPC__ ) && !defined ( __FreeBSD__ ) && !defined ( __S3E__ ) ++#elif !defined ( __EMSCRIPTEN__ ) && !defined ( __APPLE__ ) && !defined ( __APPLE_CC__ ) && !defined ( __PPC__ ) && !defined ( __FreeBSD__ ) && !defined ( __S3E__ ) + #include + #endif + +diff --git a/Source/src/GetTime.cpp b/Source/src/GetTime.cpp +index 6e30e255c..67d69ace0 100644 +--- a/Source/src/GetTime.cpp ++++ b/Source/src/GetTime.cpp +@@ -182,7 +182,7 @@ SLNet::TimeUS GetTimeUS_Windows( void ) + return curTime; + #endif // #if defined(GET_TIME_SPIKE_LIMIT) && GET_TIME_SPIKE_LIMIT>0 + } +-#elif defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__) ++#elif defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__) + SLNet::TimeUS GetTimeUS_Linux( void ) + { + timeval tp; +diff --git a/Source/src/LinuxStrings.cpp b/Source/src/LinuxStrings.cpp +index 0a5583a0c..95bb2a093 100644 +--- a/Source/src/LinuxStrings.cpp ++++ b/Source/src/LinuxStrings.cpp +@@ -13,7 +13,7 @@ + * license found in the license.txt file in the root directory of this source tree. + */ + +-#if (defined(__GNUC__) || defined(__ARMCC_VERSION) || defined(__GCCXML__) || defined(__S3E__) ) && !defined(_WIN32) ++#if (defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__ARMCC_VERSION) || defined(__GCCXML__) || defined(__S3E__) ) && !defined(_WIN32) + #include + #ifndef _stricmp + int _stricmp(const char* s1, const char* s2) +diff --git a/Source/src/PacketLogger.cpp b/Source/src/PacketLogger.cpp +index 65c19500a..f82383959 100644 +--- a/Source/src/PacketLogger.cpp ++++ b/Source/src/PacketLogger.cpp +@@ -504,7 +504,7 @@ void PacketLogger::SetSuffix(const char *_suffix) + } + void PacketLogger::GetLocalTime(char buffer[128]) + { +-#if defined(_WIN32) && !defined(__GNUC__) && !defined(__GCCXML__) ++#if defined(_WIN32) && !defined(__GNUC__) && !defined(__GCCXML__) && !defined(__EMSCRIPTEN__) + time_t rawtime; + struct timeval tv; + // If you get an arror about an incomplete type, just delete this file +diff --git a/Source/src/RakNetSocket2_Berkley.cpp b/Source/src/RakNetSocket2_Berkley.cpp +index 0592beed1..1a4aac8a2 100644 +--- a/Source/src/RakNetSocket2_Berkley.cpp ++++ b/Source/src/RakNetSocket2_Berkley.cpp +@@ -203,7 +203,7 @@ RNS2BindResult RNS2_Berkley::BindSharedIPV4( RNS2_BerkleyBindParameters *bindPar + #if defined(_WIN32) + closesocket__(rns2Socket); + return BR_FAILED_TO_BIND_SOCKET; +-#elif (defined(__GNUC__) || defined(__GCCXML__) ) && !defined(_WIN32) ++#elif (defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__GCCXML__) ) && !defined(_WIN32) + closesocket__(rns2Socket); + switch (errno) + { +diff --git a/Source/src/RakNetSocket2_Windows_Linux_360.cpp b/Source/src/RakNetSocket2_Windows_Linux_360.cpp +index ee7aedad9..de4e95628 100644 +--- a/Source/src/RakNetSocket2_Windows_Linux_360.cpp ++++ b/Source/src/RakNetSocket2_Windows_Linux_360.cpp +@@ -20,7 +20,7 @@ + #ifndef RAKNETSOCKET2_WINDOWS_LINUX_360_CPP + #define RAKNETSOCKET2_WINDOWS_LINUX_360_CPP + +-#if (defined(_WIN32) || defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__) ) && !defined(WINDOWS_STORE_RT) && !defined(__native_client__) ++#if (defined(_WIN32) || defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__) ) && !defined(WINDOWS_STORE_RT) && !defined(__native_client__) + + RNS2SendResult RNS2_Windows_Linux_360::Send_Windows_Linux_360NoVDP( RNS2Socket rns2Socket, RNS2_SendParameters *sendParameters, const char *file, unsigned int line ) { + +diff --git a/Source/src/SignaledEvent.cpp b/Source/src/SignaledEvent.cpp +index 5577cb442..3f623fcf8 100644 +--- a/Source/src/SignaledEvent.cpp ++++ b/Source/src/SignaledEvent.cpp +@@ -17,7 +17,7 @@ + #include "slikenet/assert.h" + #include "slikenet/sleep.h" + +-#if defined(__GNUC__) ++#if defined(__GNUC__) || defined(__EMSCRIPTEN__) + #include + #include + #endif +diff --git a/Source/src/SocketLayer.cpp b/Source/src/SocketLayer.cpp +index fd6722e7c..1a50128b4 100644 +--- a/Source/src/SocketLayer.cpp ++++ b/Source/src/SocketLayer.cpp +@@ -26,7 +26,7 @@ + #include "slikenet/SocketDefines.h" + #include "slikenet/linux_adapter.h" + #include "slikenet/osx_adapter.h" +-#if (defined(__GNUC__) || defined(__GCCXML__)) && !defined(__WIN32__) ++#if (defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__GCCXML__)) && !defined(__WIN32__) + #include + #endif + +diff --git a/Source/src/TCPInterface.cpp b/Source/src/TCPInterface.cpp +index 0ca8a868d..ec3f181ee 100644 +--- a/Source/src/TCPInterface.cpp ++++ b/Source/src/TCPInterface.cpp +@@ -44,7 +44,7 @@ + #include "slikenet/Itoa.h" + #include "slikenet/SocketLayer.h" + #include "slikenet/SocketDefines.h" +-#if (defined(__GNUC__) || defined(__GCCXML__)) && !defined(__WIN32__) ++#if (defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__GCCXML__)) && !defined(__WIN32__) + #include + #endif + +diff --git a/Source/src/UDPForwarder.cpp b/Source/src/UDPForwarder.cpp +index 317dc9f8b..20d067531 100644 +--- a/Source/src/UDPForwarder.cpp ++++ b/Source/src/UDPForwarder.cpp +@@ -212,7 +212,7 @@ void UDPForwarder::RecvFrom(SLNet::TimeMS curTime, ForwardEntry *forwardEntry) + sockAddrIn.sin_family = AF_INET; + #endif + +-#if defined(__GNUC__) ++#if defined(__GNUC__) || defined(__EMSCRIPTEN__) + #if defined(MSG_DONTWAIT) + const int flag=MSG_DONTWAIT; + #else +diff --git a/Source/src/_FindFirst.cpp b/Source/src/_FindFirst.cpp +index 10fab3462..1bc7990c7 100644 +--- a/Source/src/_FindFirst.cpp ++++ b/Source/src/_FindFirst.cpp +@@ -12,7 +12,7 @@ + * Original file by the_viking, fixed by RvĀ„mulo Fernandes, fixed by Emmanuel Nars + * Should emulate windows finddata structure + */ +-#if (defined(__GNUC__) || defined(__GCCXML__)) && !defined(_WIN32) ++#if (defined(__EMSCRIPTEN__) || defined(__GNUC__) || defined(__GCCXML__)) && !defined(_WIN32) + #include "slikenet/_FindFirst.h" + #include "slikenet/DS_List.h" + +diff --git a/Source/src/gettimeofday.cpp b/Source/src/gettimeofday.cpp +index 0391948d2..83112d263 100644 +--- a/Source/src/gettimeofday.cpp ++++ b/Source/src/gettimeofday.cpp +@@ -13,7 +13,7 @@ + * license found in the license.txt file in the root directory of this source tree. + */ + +-#if defined(_WIN32) && !defined(__GNUC__) &&!defined(__GCCXML__) ++#if defined(_WIN32) && !defined(__GNUC__) &&!defined(__GCCXML__) && !defined(__EMSCRIPTEN__) + + #include "slikenet/gettimeofday.h" + +diff --git a/Source/src/linux_adapter.cpp b/Source/src/linux_adapter.cpp +index fe25abe96..9d1f66e71 100644 +--- a/Source/src/linux_adapter.cpp ++++ b/Source/src/linux_adapter.cpp +@@ -8,7 +8,7 @@ + * This file defines adapters for all MS-specific functions used throughout SLikeNet. + */ + +-#ifdef __linux__ ++#if defined(__linux__) || defined(__EMSCRIPTEN__) + #include "slikenet/linux_adapter.h" + + #include // for std::max, std::min diff --git a/overlay_ports/slikenet/fix-install.patch b/overlay_ports/slikenet/fix-install.patch new file mode 100644 index 0000000000..b671d7b5af --- /dev/null +++ b/overlay_ports/slikenet/fix-install.patch @@ -0,0 +1,51 @@ +diff --git a/Lib/DLL/CMakeLists.txt b/Lib/DLL/CMakeLists.txt +index 7f6453d..48f9562 100644 +--- a/Lib/DLL/CMakeLists.txt ++++ b/Lib/DLL/CMakeLists.txt +@@ -50,6 +50,7 @@ ELSE(WIN32 AND NOT UNIX) + ENDIF(WIN32 AND NOT UNIX) + + target_link_libraries(SLikeNetDLL ${SLIKENET_LIBRARY_LIBS}) ++if(0) + IF(NOT WIN32 OR UNIX) + configure_file(../../slikenet-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/slikenet-config-version.cmake @ONLY) + +@@ -60,3 +61,12 @@ IF(NOT WIN32 OR UNIX) + INSTALL(FILES ../../slikenet-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/slikenet-config-version.cmake DESTINATION lib/slikenet-${SLikeNet_VERSION}) + INSTALL(EXPORT SLikeNetDLL DESTINATION lib/slikenet-${SLikeNet_VERSION}) + ENDIF(NOT WIN32 OR UNIX) ++endif() ++ ++install(TARGETS SLikeNetDLL ++ EXPORT SLikeNetDLL ++ RUNTIME DESTINATION bin ++ LIBRARY DESTINATION lib ++ ARCHIVE DESTINATION lib) ++INSTALL(FILES ${ALL_HEADER_SRCS} DESTINATION include/slikenet) ++install(EXPORT SLikeNetDLL FILE slikenetTargets.cmake DESTINATION share/slikenet) +diff --git a/Lib/LibStatic/CMakeLists.txt b/Lib/LibStatic/CMakeLists.txt +index f936fa5..a5dcc4f 100644 +--- a/Lib/LibStatic/CMakeLists.txt ++++ b/Lib/LibStatic/CMakeLists.txt +@@ -50,6 +50,8 @@ ELSE(WIN32 AND NOT UNIX) + ENDIF(WIN32 AND NOT UNIX) + + target_link_libraries(SLikeNetLibStatic ${SLIKENET_LIBRARY_LIBS}) ++ ++if(0) + IF(WIN32 AND NOT UNIX) + IF(NOT ${CMAKE_GENERATOR} STREQUAL "MSYS Makefiles") + set_target_properties(SLikeNetLibStatic PROPERTIES STATIC_LIBRARY_FLAGS "/NODEFAULTLIB:\"LIBCD.lib LIBCMTD.lib MSVCRT.lib\"" ) +@@ -64,3 +66,12 @@ ELSE(WIN32 AND NOT UNIX) + INSTALL(FILES ../../slikenet-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/slikenet-config-version.cmake DESTINATION lib/slikenet-${SLikeNet_VERSION}) + INSTALL(EXPORT SLikeNetLibStatic FILE slikenet.cmake DESTINATION lib/slikenet-${SLikeNet_VERSION}) + ENDIF(WIN32 AND NOT UNIX) ++endif() ++ ++INSTALL(TARGETS SLikeNetLibStatic ++ EXPORT SLikeNetLibStatic ++ RUNTIME DESTINATION bin ++ LIBRARY DESTINATION lib ++ ARCHIVE DESTINATION lib) ++INSTALL(FILES ${ALL_HEADER_SRCS} DESTINATION include/slikenet) ++INSTALL(EXPORT SLikeNetLibStatic FILE slikenetTargets.cmake DESTINATION share/slikenet) diff --git a/overlay_ports/slikenet/portfile.cmake b/overlay_ports/slikenet/portfile.cmake new file mode 100644 index 0000000000..ea29d0dbf7 --- /dev/null +++ b/overlay_ports/slikenet/portfile.cmake @@ -0,0 +1,36 @@ +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO SLikeSoft/SLikeNet + REF 358462052fce7e585fc1cce0a17a7042ba724c08 + SHA512 2c932b0a7910ec36dd6a340dd841cefcf259fbdadadff220747d13752181ea14e3c5f05331beb36dea21c0de360edc270ff4c55375bbea23ee2149828f07e9ab + HEAD_REF master + PATCHES + fix-install.patch + fix-emscripten.patch +) +#Uses an outdated OpenSSL version and is in an experimental namespace any way. As such we delete it here +file(REMOVE_RECURSE "${SOURCE_PATH}/Source/src/crypto" "${SOURCE_PATH}/Source/include/slikenet/crypto") + +string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" SLIKENET_ENABLE_STATIC) +string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" SLIKENET_ENABLE_DLL) + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}" + OPTIONS + -DSLIKENET_ENABLE_DLL=${SLIKENET_ENABLE_DLL} + -DSLIKENET_ENABLE_STATIC=${SLIKENET_ENABLE_STATIC} + -DSLIKENET_ENABLE_SAMPLES=FALSE +) + +vcpkg_cmake_install() + +vcpkg_copy_pdbs() + +vcpkg_cmake_config_fixup(CONFIG_PATH share/slikenet) + +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include ${CURRENT_PACKAGES_DIR}/debug/share) + +configure_file("${CMAKE_CURRENT_LIST_DIR}/slikenet-config.cmake" "${CURRENT_PACKAGES_DIR}/share/slikenet/slikenet-config.cmake" COPYONLY) +configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake" "${CURRENT_PACKAGES_DIR}/share/slikenet/vcpkg-cmake-wrapper.cmake" COPYONLY) +file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}") +file(INSTALL "${SOURCE_PATH}/license.txt" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright) diff --git a/overlay_ports/slikenet/slikenet-config.cmake b/overlay_ports/slikenet/slikenet-config.cmake new file mode 100644 index 0000000000..dbbf5e1bf0 --- /dev/null +++ b/overlay_ports/slikenet/slikenet-config.cmake @@ -0,0 +1,4 @@ +include(CMakeFindDependencyMacro) +find_dependency(OpenSSL) +set(slikenet_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../include") +include(${CMAKE_CURRENT_LIST_DIR}/slikenetTargets.cmake) diff --git a/overlay_ports/slikenet/usage b/overlay_ports/slikenet/usage new file mode 100644 index 0000000000..bd54611108 --- /dev/null +++ b/overlay_ports/slikenet/usage @@ -0,0 +1,4 @@ +The package slikenet provides CMake targets: + + find_package(slikenet CONFIG REQUIRED) + target_link_libraries(main PRIVATE SLikeNet) diff --git a/overlay_ports/slikenet/vcpkg-cmake-wrapper.cmake b/overlay_ports/slikenet/vcpkg-cmake-wrapper.cmake new file mode 100644 index 0000000000..50c5c3a9c2 --- /dev/null +++ b/overlay_ports/slikenet/vcpkg-cmake-wrapper.cmake @@ -0,0 +1,11 @@ +_find_package(${ARGS}) + +if(NOT TARGET SLikeNet AND TARGET SLikeNetDLL) +add_library(SLikeNet INTERFACE IMPORTED) +set_target_properties(SLikeNet PROPERTIES INTERFACE_LINK_LIBRARIES SLikeNetDLL) +endif() + +if(NOT TARGET SLikeNet AND TARGET SLikeNetLibStatic) +add_library(SLikeNet INTERFACE IMPORTED) +set_target_properties(SLikeNet PROPERTIES INTERFACE_LINK_LIBRARIES SLikeNetLibStatic) +endif() diff --git a/overlay_ports/slikenet/vcpkg.json b/overlay_ports/slikenet/vcpkg.json new file mode 100644 index 0000000000..e0d0ae4f9b --- /dev/null +++ b/overlay_ports/slikenet/vcpkg.json @@ -0,0 +1,19 @@ +{ + "name": "slikenet", + "version-date": "2021-06-07", + "port-version": 2, + "description": "SLikeNetT is an Open Source/Free Software cross-platform network engine written in C++ and specifially designed for games (and applications which have comparable requirements on a network engine like games) building upon the discontinued RakNet network engine which had more than 13 years of active development.", + "homepage": "https://github.com/SLikeSoft/SLikeNet", + "supports": "!uwp", + "dependencies": [ + "openssl", + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +} diff --git a/papyrus-vm/src/papyrus-vm-lib/ActivePexInstance.cpp b/papyrus-vm/src/papyrus-vm-lib/ActivePexInstance.cpp index 29123cc9f6..d85dbe8893 100644 --- a/papyrus-vm/src/papyrus-vm-lib/ActivePexInstance.cpp +++ b/papyrus-vm/src/papyrus-vm-lib/ActivePexInstance.cpp @@ -4,12 +4,12 @@ #include "papyrus-vm/VirtualMachine.h" #include #include // tolower +#include #include +#include #include #include -#include - namespace { bool IsSelfStr(const VarValue& v) { diff --git a/skymp5-server/CMakeLists.txt b/skymp5-server/CMakeLists.txt index 6b42a06765..eb9677ef43 100644 --- a/skymp5-server/CMakeLists.txt +++ b/skymp5-server/CMakeLists.txt @@ -11,7 +11,9 @@ yarn_execute_command( ) # Find node-addon-api -find_package(unofficial-node-addon-api REQUIRED) +if(NOT EMSCRIPTEN) + find_package(unofficial-node-addon-api REQUIRED) +endif() # Add C++ part of the server (except cpp/addon) add_subdirectory(cpp) @@ -20,35 +22,37 @@ add_subdirectory(cpp) add_subdirectory(ts) # Add C++ addon for NodeJS -file(GLOB_RECURSE sources "${SKYMP5_SERVER_SOURCE_DIR}/cpp/addon/*") -if(MSVC) - list(APPEND sources "${CMAKE_SOURCE_DIR}/.clang-format") -endif() -add_library(${PROJECT_NAME} SHARED ${sources}) -set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "scam_native" PREFIX "" SUFFIX ".node") -target_link_libraries(${PROJECT_NAME} PRIVATE unofficial::node-addon-api::node-addon-api) -target_include_directories(${PROJECT_NAME} PRIVATE ${SKYMP5_SERVER_SOURCE_DIR}/cpp/addon) - -# Make 'cmake --build . --target skymp5-server' building typescript part as well -add_dependencies(${PROJECT_NAME} skymp5-server-ts) - -# Put build artifacts into build/dist/server -if(WIN32) - set_target_properties(${PROJECT_NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/dist/server" - RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/dist/server" - ) -else() - add_custom_command( - TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_BINARY_DIR}/dist/server/$ - ) +if(NOT EMSCRIPTEN) + file(GLOB_RECURSE sources "${SKYMP5_SERVER_SOURCE_DIR}/cpp/addon/*") + if(MSVC) + list(APPEND sources "${CMAKE_SOURCE_DIR}/.clang-format") + endif() + add_library(${PROJECT_NAME} SHARED ${sources}) + set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "scam_native" PREFIX "" SUFFIX ".node") + target_link_libraries(${PROJECT_NAME} PRIVATE unofficial::node-addon-api::node-addon-api) + target_include_directories(${PROJECT_NAME} PRIVATE ${SKYMP5_SERVER_SOURCE_DIR}/cpp/addon) + + # Make 'cmake --build . --target skymp5-server' building typescript part as well + add_dependencies(${PROJECT_NAME} skymp5-server-ts) + + # Put build artifacts into build/dist/server + if(WIN32) + set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/dist/server" + RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/dist/server" + ) + else() + add_custom_command( + TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_BINARY_DIR}/dist/server/$ + ) + endif() + + target_link_libraries(${PROJECT_NAME} PRIVATE mp_common server_guest_lib localization-provider) + list(APPEND VCPKG_DEPENDENT ${PROJECT_NAME}) + apply_default_settings(TARGETS ${PROJECT_NAME}) endif() -target_link_libraries(${PROJECT_NAME} PRIVATE mp_common server_guest_lib localization-provider) -list(APPEND VCPKG_DEPENDENT ${PROJECT_NAME}) -apply_default_settings(TARGETS ${PROJECT_NAME}) - # All targets are ready if(WIN32) @@ -85,20 +89,22 @@ endif() message(STATUS "esm_prefix is '${esm_prefix}'") -add_custom_command( - TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -DESM_PREFIX=${esm_prefix} -DSERVER_SETTINGS_JSON_PATH=${CMAKE_BINARY_DIR}/dist/server/server-settings.json -DOFFLINE_MODE=${OFFLINE_MODE} -P ${CMAKE_SOURCE_DIR}/cmake/scripts/generate_server_settings.cmake -) +if(TARGET ${PROJECT_NAME}) + add_custom_command( + TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -DESM_PREFIX=${esm_prefix} -DSERVER_SETTINGS_JSON_PATH=${CMAKE_BINARY_DIR}/dist/server/server-settings.json -DOFFLINE_MODE=${OFFLINE_MODE} -P ${CMAKE_SOURCE_DIR}/cmake/scripts/generate_server_settings.cmake + ) -add_custom_command( - TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${SKYMP5_SERVER_SOURCE_DIR}/package.json ${CMAKE_BINARY_DIR}/dist/server/package.json -) + add_custom_command( + TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${SKYMP5_SERVER_SOURCE_DIR}/package.json ${CMAKE_BINARY_DIR}/dist/server/package.json + ) -add_custom_command( - TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${SKYMP5_SERVER_SOURCE_DIR}/yarn.lock ${CMAKE_BINARY_DIR}/dist/server/yarn.lock -) + add_custom_command( + TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${SKYMP5_SERVER_SOURCE_DIR}/yarn.lock ${CMAKE_BINARY_DIR}/dist/server/yarn.lock + ) +endif() file(GLOB_RECURSE standard_scripts ${CMAKE_CURRENT_SOURCE_DIR}/standard_scripts/* diff --git a/skymp5-server/cpp/CMakeLists.txt b/skymp5-server/cpp/CMakeLists.txt index c9e5832fed..789416c8f6 100644 --- a/skymp5-server/cpp/CMakeLists.txt +++ b/skymp5-server/cpp/CMakeLists.txt @@ -90,9 +90,6 @@ target_include_directories(localization-provider PUBLIC "${CMAKE_CURRENT_SOURCE_ find_path(CATCH_INCLUDE_DIR NAMES catch.hpp PATH_SUFFIXES catch2) get_filename_component(CATCH_INCLUDE_DIR ${CATCH_INCLUDE_DIR} DIRECTORY) -find_path(SPARSEPP_INCLUDE_DIR NAMES spp.h PATH_SUFFIXES sparsepp) -get_filename_component(SPARSEPP_INCLUDE_DIR ${SPARSEPP_INCLUDE_DIR} DIRECTORY) - find_path(JSON_INCLUDE_DIR NAMES json.hpp PATH_SUFFIXES nlohmann) get_filename_component(JSON_INCLUDE_DIR ${JSON_INCLUDE_DIR} DIRECTORY) @@ -104,13 +101,15 @@ find_package(slikenet CONFIG REQUIRED) find_package(ZLIB REQUIRED) -find_package(mongocxx REQUIRED) -find_package(mongoc-1.0 CONFIG REQUIRED) +if(NOT EMSCRIPTEN) + find_package(mongocxx REQUIRED) + find_package(mongoc-1.0 CONFIG REQUIRED) +endif() find_package(OpenSSL REQUIRED) # MacOS not supported by rsm-bsa -if(NOT APPLE) +if(NOT APPLE AND NOT EMSCRIPTEN) find_package(bsa CONFIG REQUIRED) endif() @@ -118,14 +117,22 @@ find_package(libzippp REQUIRED) foreach(target ${VCPKG_DEPENDENT}) target_include_directories(${target} PUBLIC ${CATCH_INCLUDE_DIR}) - target_include_directories(${target} PUBLIC ${SPARSEPP_INCLUDE_DIR}) target_include_directories(${target} PUBLIC ${JSON_INCLUDE_DIR}) target_link_libraries(${target} PUBLIC spdlog::spdlog) target_link_libraries(${target} PUBLIC simdjson::simdjson) + target_link_libraries(${target} PUBLIC SLikeNet) + target_link_libraries(${target} PUBLIC ZLIB::ZLIB) - target_link_libraries(${target} PUBLIC mongo::mongocxx_static mongo::bsoncxx_static mongo::mongoc_static mongo::bson_static) + + if(TARGET mongo::mongocxx_static) + target_link_libraries(${target} PUBLIC mongo::mongocxx_static mongo::bsoncxx_static mongo::mongoc_static mongo::bson_static) + else() + target_compile_definitions(${target} PUBLIC NO_MONGO=1) + endif() + target_link_libraries(${target} PUBLIC OpenSSL::SSL OpenSSL::Crypto) + if(TARGET bsa::bsa) target_link_libraries(${target} PUBLIC bsa::bsa) else() @@ -137,6 +144,8 @@ foreach(target ${VCPKG_DEPENDENT}) target_link_libraries(${target} PUBLIC pthread resolv m) elseif(WIN32) target_link_libraries(${target} PUBLIC Secur32.lib Crypt32.lib Dnsapi.lib Bcrypt.lib) + elseif(EMSCRIPTEN) + # ... elseif(UNIX) target_link_libraries(${target} PUBLIC pthread resolv rt m) endif() diff --git a/skymp5-server/cpp/mp_common/IdManager.h b/skymp5-server/cpp/mp_common/IdManager.h index 18df5546e8..a2d968915f 100644 --- a/skymp5-server/cpp/mp_common/IdManager.h +++ b/skymp5-server/cpp/mp_common/IdManager.h @@ -1,8 +1,7 @@ #pragma once #include "Networking.h" #include "RakNet.h" -#include -#include +#include #include class IdManager @@ -20,7 +19,7 @@ class IdManager RakNetGUID find(userid id) const noexcept; private: - spp::sparse_hash_map idByGuid; + std::unordered_map idByGuid; std::vector guidById; userid nextId = 0; const userid maxConnections = 0; diff --git a/skymp5-server/cpp/server_guest_lib/WorldState.cpp b/skymp5-server/cpp/server_guest_lib/WorldState.cpp index 38254f7d44..55dd9bdfb2 100644 --- a/skymp5-server/cpp/server_guest_lib/WorldState.cpp +++ b/skymp5-server/cpp/server_guest_lib/WorldState.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/skymp5-server/cpp/server_guest_lib/WorldState.h b/skymp5-server/cpp/server_guest_lib/WorldState.h index 24554fb9ec..d161f3946c 100644 --- a/skymp5-server/cpp/server_guest_lib/WorldState.h +++ b/skymp5-server/cpp/server_guest_lib/WorldState.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -287,9 +286,9 @@ class WorldState std::map> loadedChunks; }; - spp::sparse_hash_map> forms; + std::unordered_map> forms; std::unordered_map loadOrderMap; - spp::sparse_hash_map grids; + std::unordered_map grids; std::unique_ptr formIdxManager; std::vector formByIdxUnreliable; espm::Loader* espm = nullptr; diff --git a/skymp5-server/cpp/server_guest_lib/database_drivers/MongoDatabase.cpp b/skymp5-server/cpp/server_guest_lib/database_drivers/MongoDatabase.cpp index 8ba70a6495..76d8313e85 100644 --- a/skymp5-server/cpp/server_guest_lib/database_drivers/MongoDatabase.cpp +++ b/skymp5-server/cpp/server_guest_lib/database_drivers/MongoDatabase.cpp @@ -1,17 +1,21 @@ #include "MongoDatabase.h" #include "JsonUtils.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +#ifndef NO_MONGO +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + #include #include #include @@ -20,14 +24,33 @@ struct MongoDatabase::Impl { +#ifndef NO_MONGO const std::string uri; const std::string name; const char* const collectionName = "changeForms"; std::shared_ptr pool; +#endif }; +#ifdef NO_MONGO +MongoDatabase::MongoDatabase(std::string uri_, std::string name_) +{ + throw std::runtime_error("MongoDB is not supported in this build"); +} +size_t MongoDatabase::Upsert(std::vector>&&) +{ + return 0; +} + +void MongoDatabase::Iterate(const IterateCallback&) +{ +} + +#endif + +#ifndef NO_MONGO MongoDatabase::MongoDatabase(std::string uri_, std::string name_) { static mongocxx::instance g_instance; @@ -279,3 +302,5 @@ std::string MongoDatabase::Sha256(const std::string& str) return BytesToHexString(hash, SHA256_DIGEST_LENGTH); } + +#endif // #ifndef NO_MONGO diff --git a/skymp5-server/cpp/server_guest_lib/formulas/SweetPieDamageFormula.cpp b/skymp5-server/cpp/server_guest_lib/formulas/SweetPieDamageFormula.cpp index 0a3b53be97..18a8926552 100644 --- a/skymp5-server/cpp/server_guest_lib/formulas/SweetPieDamageFormula.cpp +++ b/skymp5-server/cpp/server_guest_lib/formulas/SweetPieDamageFormula.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include "HitData.h" diff --git a/skyrim-platform/src/platform_se/CMakeLists.txt b/skyrim-platform/src/platform_se/CMakeLists.txt index 873633ceae..77ccd21872 100644 --- a/skyrim-platform/src/platform_se/CMakeLists.txt +++ b/skyrim-platform/src/platform_se/CMakeLists.txt @@ -145,29 +145,35 @@ if(NOT "${SKIP_SKYRIM_PLATFORM_BUILDING}") add_custom_target(RestartGame ALL COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/touch_$) add_dependencies(RestartGame ${DEPENDENCIES_FOR_CUSTOM_TARGETS}) endif() + + # can't run executables on Emscripten + if(NOT EMSCRIPTEN) + add_executable(TSConverter ${CMAKE_CURRENT_LIST_DIR}/codegen/TSConverter.cpp) + apply_default_settings(TARGETS TSConverter) + set_target_properties(TSConverter PROPERTIES CXX_STANDARD 20) + + set(CONVERT_FILES_DIR ${CMAKE_CURRENT_LIST_DIR}/codegen/convert-files/) + list(APPEND CODEGEN_ARGS + "${CONVERT_FILES_DIR}/FunctionsDump.txt" + "${CONVERT_FILES_DIR}/Definitions.txt" + "${CMAKE_CURRENT_BINARY_DIR}/_codegen/skyrimPlatform.ts" + ) + add_custom_target(codegen ALL COMMAND $ ${CODEGEN_ARGS}) + add_dependencies(codegen TSConverter) - add_executable(TSConverter ${CMAKE_CURRENT_LIST_DIR}/codegen/TSConverter.cpp) - apply_default_settings(TARGETS TSConverter) - set_target_properties(TSConverter PROPERTIES CXX_STANDARD 20) - - set(CONVERT_FILES_DIR ${CMAKE_CURRENT_LIST_DIR}/codegen/convert-files/) - list(APPEND CODEGEN_ARGS - "${CONVERT_FILES_DIR}/FunctionsDump.txt" - "${CONVERT_FILES_DIR}/Definitions.txt" - "${CMAKE_CURRENT_BINARY_DIR}/_codegen/skyrimPlatform.ts" - ) - add_custom_target(codegen ALL COMMAND $ ${CODEGEN_ARGS}) - add_dependencies(codegen TSConverter) - - # force "skyrim-platform" custom target to be built strictly after codegen - list(APPEND DEPENDENCIES_FOR_CUSTOM_TARGETS codegen) + # force "skyrim-platform" custom target to be built strictly after codegen + list(APPEND DEPENDENCIES_FOR_CUSTOM_TARGETS codegen) + endif() # this target was originally called pack, now it is called skyrim-platform # so we can use add_dependencies(x skyrim-platform) in other projects add_custom_target(skyrim-platform ALL COMMAND yarn --cwd \"${SKYRIM_PLATFORM_SOURCE_DIR}/tools/dev_service\" run pack$<$:-debug> ) - add_dependencies(skyrim-platform ${DEPENDENCIES_FOR_CUSTOM_TARGETS}) + + if(DEPENDENCIES_FOR_CUSTOM_TARGETS) + add_dependencies(skyrim-platform ${DEPENDENCIES_FOR_CUSTOM_TARGETS}) + endif() endif() if(MSVC) @@ -178,9 +184,11 @@ endif() # TSConverter vcpkg deps -find_path(JSON_INCLUDE_DIR NAMES json.hpp PATH_SUFFIXES nlohmann) -get_filename_component(JSON_INCLUDE_DIR ${JSON_INCLUDE_DIR} DIRECTORY) -target_include_directories(TSConverter PUBLIC ${JSON_INCLUDE_DIR}) +if(TARGET TSConverter) + find_path(JSON_INCLUDE_DIR NAMES json.hpp PATH_SUFFIXES nlohmann) + get_filename_component(JSON_INCLUDE_DIR ${JSON_INCLUDE_DIR} DIRECTORY) + target_include_directories(TSConverter PUBLIC ${JSON_INCLUDE_DIR}) +endif() if(MSVC) diff --git a/skyrim-platform/tools/dev_service/index.js b/skyrim-platform/tools/dev_service/index.js index c74c029bf6..255a1809ec 100644 --- a/skyrim-platform/tools/dev_service/index.js +++ b/skyrim-platform/tools/dev_service/index.js @@ -198,12 +198,24 @@ const watchCallback = (_eventType, fileName) => { // On Linux, we would not have this directory created yet createDirectory(path.join(distDir, "Data/Platform/Modules")); + + // Fallback to spDotTsPath2 if codegen/tsconverter is not available (Emscripten build) + const spDotTsPath1 = path.join(bin, `_codegen/skyrimPlatform.ts`); + const spDotTsPath2 = path.join(sourceDir, "src/platform_se/codegen/convert-files/skyrimPlatform.ts"); + let spDotTsPath; + if (fs.existsSync(spDotTsPath1)) { + spDotTsPath = spDotTsPath1; + } else if (fs.existsSync(spDotTsPath2)) { + spDotTsPath = spDotTsPath2; + } else { + throw new Error(`Cannot find skyrimPlatform.ts in ${spDotTsPath1} or ${spDotTsPath2}`); + } cp( - path.join(bin, `_codegen/skyrimPlatform.ts`), + spDotTsPath, path.join(distDir, "Data/Platform/Modules") ); cp( - path.join(bin, `_codegen/skyrimPlatform.ts`), + spDotTsPath, path.join(sourceDir, "src/platform_se/codegen/convert-files") ); diff --git a/vcpkg b/vcpkg index a34c873a97..333ba63a16 160000 --- a/vcpkg +++ b/vcpkg @@ -1 +1 @@ -Subproject commit a34c873a9717a888f58dc05268dea15592c2f0ff +Subproject commit 333ba63a16024f05f9172fe403f9eced000389e5 diff --git a/vcpkg.json b/vcpkg.json index 8cbf884eea..26b46a2386 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -10,19 +10,24 @@ "zlib", "spdlog", "catch2", - "sparsepp", - "slikenet", - "mongo-cxx-driver", "simdjson", "robin-hood-hashing", "simpleini", - "node-addon-api", "bshoshany-thread-pool", "makeid", "libzippp", + "slikenet", + { + "name": "mongo-cxx-driver", + "platform": "!emscripten" + }, + { + "name": "node-addon-api", + "platform": "!emscripten" + }, { "name": "rsm-bsa", - "platform": "!osx" + "platform": "!osx & !emscripten" }, { "name": "frida-gum",