cmake_minimum_required(VERSION 3.16) project(GameServer LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(GAME_ROOT "${CMAKE_CURRENT_LIST_DIR}/..") find_package(Threads REQUIRED) find_package(Eigen3 3.3 CONFIG QUIET) if(NOT TARGET Eigen3::Eigen) set(EIGEN_BUNDLED_DIR "${GAME_ROOT}/thirdparty/eigen-5.0.0") if(NOT EXISTS "${EIGEN_BUNDLED_DIR}/Eigen/Core") message(FATAL_ERROR "Eigen3 was not found. Install Eigen3 or configure the graphical " "project once to populate thirdparty/eigen-5.0.0.") endif() add_library(game_server_eigen INTERFACE) target_include_directories(game_server_eigen INTERFACE "${EIGEN_BUNDLED_DIR}") add_library(Eigen3::Eigen ALIAS game_server_eigen) endif() add_library(game_server_core STATIC "${GAME_ROOT}/src/Campaign.cpp" "${GAME_ROOT}/src/Campaign.h" "${GAME_ROOT}/src/CharacterState.cpp" "${GAME_ROOT}/src/CharacterState.h" "${GAME_ROOT}/src/GameState.cpp" "${GAME_ROOT}/src/GameState.h" "${GAME_ROOT}/src/ISaveable.h" "${GAME_ROOT}/src/Localization.cpp" "${GAME_ROOT}/src/Localization.h" "${GAME_ROOT}/src/LocationGameState.cpp" "${GAME_ROOT}/src/LocationGameState.h" "${GAME_ROOT}/src/LocationState.cpp" "${GAME_ROOT}/src/LocationState.h" "${GAME_ROOT}/src/NpcCar.cpp" "${GAME_ROOT}/src/NpcCar.h" "${GAME_ROOT}/src/content/LocationDefinition.cpp" "${GAME_ROOT}/src/content/LocationDefinition.h" "${GAME_ROOT}/src/game_server/IGameServer.h" "${GAME_ROOT}/src/game_server/IGameServerLifecycle.h" "${GAME_ROOT}/src/game_server/InternalGameServer.cpp" "${GAME_ROOT}/src/game_server/InternalGameServer.h" "${GAME_ROOT}/src/items/InteractiveObjectState.cpp" "${GAME_ROOT}/src/items/InteractiveObjectState.h" "${GAME_ROOT}/src/items/Inventory.cpp" "${GAME_ROOT}/src/items/Item.h" "${GAME_ROOT}/src/navigation/PathFinder.cpp" "${GAME_ROOT}/src/navigation/PathFinder.h" "${GAME_ROOT}/src/quest/QuestJournal.cpp" "${GAME_ROOT}/src/quest/QuestJournal.h" "${GAME_ROOT}/src/quest/QuestTypes.h" "${GAME_ROOT}/src/utils/HeadlessUtils.cpp" "${GAME_ROOT}/src/utils/Utils.h" ) source_group(TREE "${GAME_ROOT}/src" PREFIX "Source" FILES "${GAME_ROOT}/src/Campaign.cpp" "${GAME_ROOT}/src/Campaign.h" "${GAME_ROOT}/src/CharacterState.cpp" "${GAME_ROOT}/src/CharacterState.h" "${GAME_ROOT}/src/GameState.cpp" "${GAME_ROOT}/src/GameState.h" "${GAME_ROOT}/src/ISaveable.h" "${GAME_ROOT}/src/Localization.cpp" "${GAME_ROOT}/src/Localization.h" "${GAME_ROOT}/src/LocationGameState.cpp" "${GAME_ROOT}/src/LocationGameState.h" "${GAME_ROOT}/src/LocationState.cpp" "${GAME_ROOT}/src/LocationState.h" "${GAME_ROOT}/src/NpcCar.cpp" "${GAME_ROOT}/src/NpcCar.h" "${GAME_ROOT}/src/content/LocationDefinition.cpp" "${GAME_ROOT}/src/content/LocationDefinition.h" "${GAME_ROOT}/src/game_server/IGameServer.h" "${GAME_ROOT}/src/game_server/IGameServerLifecycle.h" "${GAME_ROOT}/src/game_server/InternalGameServer.cpp" "${GAME_ROOT}/src/game_server/InternalGameServer.h" "${GAME_ROOT}/src/items/InteractiveObjectState.cpp" "${GAME_ROOT}/src/items/InteractiveObjectState.h" "${GAME_ROOT}/src/items/Inventory.cpp" "${GAME_ROOT}/src/items/Item.h" "${GAME_ROOT}/src/navigation/PathFinder.cpp" "${GAME_ROOT}/src/navigation/PathFinder.h" "${GAME_ROOT}/src/quest/QuestJournal.cpp" "${GAME_ROOT}/src/quest/QuestJournal.h" "${GAME_ROOT}/src/quest/QuestTypes.h" "${GAME_ROOT}/src/utils/HeadlessUtils.cpp" "${GAME_ROOT}/src/utils/Utils.h" ) target_include_directories(game_server_core PUBLIC "${GAME_ROOT}/src") target_link_libraries(game_server_core PUBLIC Eigen3::Eigen Threads::Threads) target_compile_definitions(game_server_core PRIVATE FRG_HEADLESS_SERVER=1) if(MSVC) target_compile_options(game_server_core PRIVATE /W4 /permissive-) else() target_compile_options(game_server_core PRIVATE -Wall -Wextra -Wpedantic) endif() add_executable(GameServer src/main.cpp README.md) source_group("Server" FILES src/main.cpp README.md) target_link_libraries(GameServer PRIVATE game_server_core) if(WIN32) set(BOOST_BUNDLED_DIR "${GAME_ROOT}/thirdparty/boost_1_90_0") if(NOT EXISTS "${BOOST_BUNDLED_DIR}/boost/asio.hpp") message(FATAL_ERROR "Boost was not found at thirdparty/boost_1_90_0. Configure the " "graphical project once to populate it.") endif() target_sources(GameServer PRIVATE "${GAME_ROOT}/src/game_server/NetworkProtocol.cpp" "${GAME_ROOT}/src/game_server/NetworkProtocol.h" "${GAME_ROOT}/src/game_server/WebsocketGameServer.cpp" "${GAME_ROOT}/src/game_server/WebsocketGameServer.h") target_include_directories(GameServer PRIVATE "${BOOST_BUNDLED_DIR}") target_compile_definitions( GameServer PRIVATE NETWORK WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00) target_link_libraries(GameServer PRIVATE ws2_32 mswsock) endif() include(CTest) if(BUILD_TESTING) add_executable( GameServerStateTests tests/LocationGameStateTests.cpp) target_link_libraries(GameServerStateTests PRIVATE game_server_core) source_group( "Server\\Tests" FILES tests/LocationGameStateTests.cpp) add_test( NAME GameServer.LocationState COMMAND GameServerStateTests) if(WIN32) add_executable( GameServerNetworkProtocolTests tests/NetworkProtocolTests.cpp "${GAME_ROOT}/src/game_server/NetworkProtocol.cpp" "${GAME_ROOT}/src/game_server/NetworkProtocol.h") target_link_libraries( GameServerNetworkProtocolTests PRIVATE game_server_core) add_test( NAME GameServer.NetworkProtocol COMMAND GameServerNetworkProtocolTests) add_executable( GameServerWebsocketLockstepTests tests/WebsocketLockstepTests.cpp "${GAME_ROOT}/src/game_server/NetworkProtocol.cpp" "${GAME_ROOT}/src/game_server/WebsocketGameClient.cpp" "${GAME_ROOT}/src/game_server/WebsocketGameServer.cpp") target_include_directories( GameServerWebsocketLockstepTests PRIVATE "${BOOST_BUNDLED_DIR}") target_compile_definitions( GameServerWebsocketLockstepTests PRIVATE NETWORK WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0A00) target_link_libraries( GameServerWebsocketLockstepTests PRIVATE game_server_core ws2_32 mswsock) add_test( NAME GameServer.WebsocketLockstep COMMAND GameServerWebsocketLockstepTests) endif() add_test( NAME GameServer.IdleSmoke COMMAND GameServer --ticks 2 --no-sleep) add_test( NAME GameServer.BattleZoneSharedPlayer COMMAND GameServer --campaign battle_zone --location uni_exterior --ticks 2 --no-sleep) set_tests_properties( GameServer.BattleZoneSharedPlayer PROPERTIES WORKING_DIRECTORY "${GAME_ROOT}") endif()