project(tes3mp-server)

# Start of tes3mp change
# tes3mp-server no longer links the engine's `components` library, which in 0.51
# needs OSG, MyGUI, Bullet, Recast and the ESM RefId machinery. It links
# tes3mp-wire (components/openmw-mp: packets and wire structs, no ESM) and
# RakNet, LuaJit and header-only Boost, and nothing else.
# End of tes3mp change

option(ENABLE_BREAKPAD "Enable Google Breakpad for Crash reporting" OFF)

if(ENABLE_BREAKPAD)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DENABLE_BREAKPAD")
    if (UNIX)
        set(Breakpad_Headers "${CMAKE_SOURCE_DIR}/extern/breakpad/src/client/linux")
        set(Breakpad_Library "${CMAKE_SOURCE_DIR}/extern/breakpad/src/client/linux/libbreakpad_client.a")
    elseif(WIN32)
        set(Breakpad_Headers "${CMAKE_SOURCE_DIR}/extern/breakpad/src/client/windows")
        set(Breakpad_Library "-lbreakpad_client")
    endif (UNIX)
    include_directories(${CMAKE_SOURCE_DIR}/extern/breakpad/src ${Breakpad_Headers})
endif(ENABLE_BREAKPAD)

option(BUILD_WITH_LUA "Enable Lua language" ON)
if(BUILD_WITH_LUA)

    # LuaJit is found by the root CMakeLists (USE_LUAJIT); 0.51 names the variable
    # LuaJit_INCLUDE_DIR where the 0.8.1 layer's FindLuaJit named it LuaJit_INCLUDE_DIRS.
    find_package(LuaJit REQUIRED)

    MESSAGE(STATUS "Found LuaJit_LIBRARIES: ${LuaJit_LIBRARIES}")
    MESSAGE(STATUS "Found LuaJit_INCLUDE_DIR: ${LuaJit_INCLUDE_DIR}")

    set(LuaScript_Sources
            Script/LangLua/LangLua.cpp
            Script/LangLua/LuaFunc.cpp)
    set(LuaScript_Headers ${LUA_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/extern/LuaBridge ${CMAKE_SOURCE_DIR}/extern/LuaBridge/detail
            Script/LangLua/LangLua.hpp)

endif(BUILD_WITH_LUA)

include_directories(${CMAKE_SOURCE_DIR}/extern/PicoSHA2)

set(NativeScript_Sources
        Script/LangNative/LangNative.cpp
        )
set(NativeScript_Headers
        Script/LangNative/LangNative.hpp
        )

# local files
set(SERVER
    main.cpp
    ServerRuntime.cpp
    Player.cpp
    Networking.cpp
    MasterClient.cpp
    Cell.cpp
    CellController.cpp
    Utils.cpp
    Script/Script.cpp Script/ScriptFunction.cpp
    Script/ScriptFunctions.cpp

    Script/Functions/Actors.cpp Script/Functions/Objects.cpp Script/Functions/Miscellaneous.cpp
    Script/Functions/Worldstate.cpp

    Script/Functions/Books.cpp Script/Functions/Cells.cpp Script/Functions/CharClass.cpp
    Script/Functions/Chat.cpp Script/Functions/Overhead.cpp Script/Functions/Names.cpp Script/Functions/JournalCustom.cpp Script/Functions/Services.cpp Script/Functions/ActorState.cpp Script/Functions/NavMesh.cpp Script/Functions/NodeOverlay.cpp Script/Functions/Vessels.cpp Script/Functions/RefNumIdentity.cpp Script/Functions/Frontier.cpp Script/Functions/Territory.cpp Script/Functions/Dialogue.cpp Script/Functions/Factions.cpp
    Script/Functions/GUI.cpp Script/Functions/Items.cpp Script/Functions/Mechanics.cpp
    Script/Functions/Positions.cpp Script/Functions/Quests.cpp Script/Functions/RecordsDynamic.cpp
    Script/Functions/Server.cpp Script/Functions/Settings.cpp Script/Functions/Shapeshift.cpp
    Script/Functions/Spells.cpp Script/Functions/Stats.cpp Script/Functions/Timer.cpp

    Script/API/TimerAPI.cpp Script/API/PublicFnAPI.cpp
        ${LuaScript_Sources}
        ${NativeScript_Sources}

)

set(SERVER_HEADER
        ServerRuntime.hpp
        Script/Types.hpp Script/Script.hpp Script/SystemInterface.hpp
        Script/ScriptFunction.hpp Script/Platform.hpp Script/Language.hpp
        Script/ScriptFunctions.hpp Script/API/TimerAPI.hpp Script/API/PublicFnAPI.hpp
        ${LuaScript_Headers}
        ${NativeScript_Headers}
)
source_group(tes3mp-server FILES ${SERVER} ${SERVER_HEADER})

set(PROCESSORS_ACTOR
        processors/actor/ProcessorActorAI.hpp processors/actor/ProcessorActorAIState.hpp processors/actor/ProcessorActorAnimFlags.hpp
        processors/actor/ProcessorActorAnimPlay.hpp processors/actor/ProcessorActorAttack.hpp
        processors/actor/ProcessorActorCast.hpp processors/actor/ProcessorActorCellChange.hpp
        processors/actor/ProcessorActorDeath.hpp processors/actor/ProcessorActorEquipment.hpp
        processors/actor/ProcessorActorList.hpp processors/actor/ProcessorActorPosition.hpp
        processors/actor/ProcessorActorSpeech.hpp processors/actor/ProcessorActorSpellsActive.hpp
        processors/actor/ProcessorActorStatsDynamic.hpp processors/actor/ProcessorActorTest.hpp
        )

source_group(tes3mp-server\\processors\\actor FILES ${PROCESSORS_ACTOR})

set(PROCESSORS_PLAYER
        processors/player/ProcessorChatMsg.hpp processors/player/ProcessorPlayerOverhead.hpp processors/player/ProcessorPlayerDispositionState.hpp processors/player/ProcessorPlayerMerchant.hpp processors/player/ProcessorPlayerNavMesh.hpp processors/player/ProcessorPlayerNodeOverlay.hpp processors/player/ProcessorPlayerOpenService.hpp processors/player/ProcessorGUIMessageBox.hpp
        processors/player/ProcessorPlayerAnimFlags.hpp processors/player/ProcessorPlayerAnimPlay.hpp
        processors/player/ProcessorPlayerAttack.hpp processors/player/ProcessorPlayerAttribute.hpp
        processors/player/ProcessorPlayerBook.hpp processors/player/ProcessorPlayerBounty.hpp
        processors/player/ProcessorPlayerCast.hpp processors/player/ProcessorPlayerCellChange.hpp
        processors/player/ProcessorPlayerCellState.hpp processors/player/ProcessorPlayerCharClass.hpp
        processors/player/ProcessorPlayerCharGen.hpp processors/player/ProcessorPlayerCooldowns.hpp
        processors/player/ProcessorPlayerDeath.hpp processors/player/ProcessorPlayerDisposition.hpp
        processors/player/ProcessorPlayerEquipment.hpp processors/player/ProcessorPlayerFaction.hpp
        processors/player/ProcessorPlayerInput.hpp processors/player/ProcessorPlayerInventory.hpp
        processors/player/ProcessorPlayerItemUse.hpp processors/player/ProcessorPlayerJournal.hpp
        processors/player/ProcessorPlayerPlaceholder.hpp processors/player/ProcessorPlayerLevel.hpp
        processors/player/ProcessorPlayerMiscellaneous.hpp processors/player/ProcessorPlayerPosition.hpp
        processors/player/ProcessorPlayerQuickKeys.hpp processors/player/ProcessorPlayerRest.hpp
        processors/player/ProcessorPlayerResurrect.hpp processors/player/ProcessorPlayerShapeshift.hpp
        processors/player/ProcessorPlayerSkill.hpp processors/player/ProcessorPlayerSpeech.hpp
        processors/player/ProcessorPlayerSpellbook.hpp processors/player/ProcessorPlayerSpellsActive.hpp
        processors/player/ProcessorPlayerStatsDynamic.hpp processors/player/ProcessorPlayerTopic.hpp
        )

source_group(tes3mp-server\\processors\\player FILES ${PROCESSORS_PLAYER})

set(PROCESSORS_OBJECT
        processors/object/ProcessorConsoleCommand.hpp processors/object/ProcessorConsoleRequest.hpp processors/object/ProcessorContainer.hpp
        processors/object/ProcessorDoorState.hpp processors/object/ProcessorMusicPlay.hpp
        processors/object/ProcessorObjectActivate.hpp processors/object/ProcessorObjectAnimPlay.hpp
        processors/object/ProcessorObjectDelete.hpp processors/object/ProcessorObjectDialogueChoice.hpp
        processors/object/ProcessorObjectHit.hpp processors/object/ProcessorObjectLock.hpp
        processors/object/ProcessorObjectMiscellaneous.hpp processors/object/ProcessorObjectMove.hpp
        processors/object/ProcessorObjectPlace.hpp processors/object/ProcessorObjectRestock.hpp
        processors/object/ProcessorObjectRotate.hpp processors/object/ProcessorObjectScale.hpp
        processors/object/ProcessorObjectSound.hpp processors/object/ProcessorObjectSpawn.hpp
        processors/object/ProcessorObjectState.hpp processors/object/ProcessorObjectTrap.hpp
        processors/object/ProcessorClientScriptLocal.hpp processors/object/ProcessorScriptMemberShort.hpp
        processors/object/ProcessorVideoPlay.hpp
        )

source_group(tes3mp-server\\processors\\object FILES ${PROCESSORS_OBJECT})

set(PROCESSORS_WORLDSTATE
        processors/worldstate/ProcessorClientScriptGlobal.hpp processors/worldstate/ProcessorRecordDynamic.hpp
        processors/worldstate/ProcessorWorldKillCount.hpp processors/worldstate/ProcessorWorldMap.hpp
        processors/worldstate/ProcessorWorldWeather.hpp processors/worldstate/ProcessorWorldVessel.hpp
        processors/worldstate/ProcessorWorldRefNumIdentity.hpp
        )

source_group(tes3mp-server\\processors\\worldstate FILES ${PROCESSORS_WORLDSTATE})

set(PROCESSORS
        processors/ProcessorInitializer.cpp
        processors/PlayerProcessor.cpp
        processors/ActorProcessor.cpp
        processors/ObjectProcessor.cpp
        processors/WorldstateProcessor.cpp
        )

source_group(tes3mp-server\\processors FILES ${PROCESSORS})

# tes3mp-server-default.cfg goes next to the executable, where the server looks first.
configure_resource_file(${OpenMW_SOURCE_DIR}/files/tes3mp/tes3mp-server-default.cfg
    "${OpenMW_BINARY_DIR}" "tes3mp-server-default.cfg")

# SiltVersions.hpp (SILTSTRIDER_ENGINE_REV) is generated into the build root on every
# build, the same way the engine's git-version stamp is.
if (GIT_CHECKOUT)
    if (NOT TARGET silt-version)
        add_custom_target (silt-version
            COMMAND ${CMAKE_COMMAND}
                -DGIT_EXECUTABLE=${GIT_EXECUTABLE}
                -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}
                -DVERSION_HPP_DIR=${OpenMW_BINARY_DIR}
                -P ${OpenMW_SOURCE_DIR}/cmake/SiltVersion.cmake
            VERBATIM)
    endif ()
else (GIT_CHECKOUT)
    file(WRITE "${OpenMW_BINARY_DIR}/SiltVersions.hpp"
        "#ifndef OPENMW_SILTVERSIONS_HPP\n#define OPENMW_SILTVERSIONS_HPP\n#define SILTSTRIDER_ENGINE_REV \"unknown\"\n#define SILTSTRIDER_LAUNCHER_REV \"unknown\"\n#endif\n")
endif (GIT_CHECKOUT)

# Main executable

add_executable(tes3mp-server
        ${SERVER} ${SERVER_HEADER}
        ${PROCESSORS_ACTOR} ${PROCESSORS_PLAYER} ${PROCESSORS_OBJECT} ${PROCESSORS_WORLDSTATE} ${PROCESSORS}
        ${APPLE_BUNDLE_RESOURCES}
        )

target_include_directories(tes3mp-server PRIVATE
    ${OpenMW_SOURCE_DIR}
    ${OpenMW_SOURCE_DIR}/apps/openmw-mp
    ${OpenMW_SOURCE_DIR}/extern
    ${OpenMW_BINARY_DIR}
    ${RakNet_INCLUDES}
)

if (BUILD_WITH_LUA)
    target_compile_definitions(tes3mp-server PRIVATE ENABLE_LUA)
    target_include_directories(tes3mp-server SYSTEM PRIVATE ${LuaJit_INCLUDE_DIR} ${OpenMW_SOURCE_DIR}/extern/LuaBridge)
endif ()

if (TARGET silt-version)
    add_dependencies(tes3mp-server silt-version)
endif ()
# resources/version, which the server reads at start-up for the commit hash it
# announces and checks clients against.
if (TARGET get-version)
    add_dependencies(tes3mp-server get-version)
endif ()

target_compile_options(tes3mp-server PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/permissive->)

if (OPENMW_MP_BUILD)
	target_compile_options(tes3mp-server PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/MP>)
endif()

set_target_properties(tes3mp-server PROPERTIES
    CXX_STANDARD 20
    CXX_STANDARD_REQUIRED YES
)

if (UNIX)
	target_compile_options(tes3mp-server PRIVATE -Wno-ignored-qualifiers)
endif()

target_link_libraries(tes3mp-server
    #${Boost_SYSTEM_LIBRARY}
    #${Boost_THREAD_LIBRARY}
    #${Boost_FILESYSTEM_LIBRARY}
    #${Boost_PROGRAM_OPTIONS_LIBRARY}
    ${RakNet_LIBRARY}
    tes3mp-wire
    ${LuaJit_LIBRARIES}
    ${Breakpad_Library}
)

if (WIN32)
    target_link_libraries(tes3mp-server shell32)
endif ()

if (UNIX)
    target_link_libraries(tes3mp-server dl)
    # Fix for not visible pthreads functions for linker with glibc 2.15
    if(NOT APPLE)
        target_link_libraries(tes3mp-server ${CMAKE_THREAD_LIBS_INIT})
    endif(NOT APPLE)
endif(UNIX)

if (BUILD_WITH_CODE_COVERAGE)
  add_definitions (--coverage)
  target_link_libraries(tes3mp-server gcov)
endif()

if (MSVC)
    # Debug version needs increased number of sections beyond 2^16
    if (CMAKE_CL_64)
        set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj")
    endif (CMAKE_CL_64)
    add_definitions("-D_USE_MATH_DEFINES")
endif (MSVC)

# Start of tes3mp addition
add_executable(SiltStriderWireTest SiltStriderWireTest.cpp)
target_include_directories(SiltStriderWireTest SYSTEM PRIVATE ${RakNet_INCLUDES} ${RakNet_INCLUDES}/raknet)
set_target_properties(SiltStriderWireTest PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED YES)
target_link_libraries(SiltStriderWireTest tes3mp-wire ${RakNet_LIBRARY})
if (WIN32)
    target_link_libraries(SiltStriderWireTest ws2_32 iphlpapi)
endif ()
# End of tes3mp addition
