diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 9db86f53..5af1cab3 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -50,7 +50,7 @@ jobs: - Server name: Test runs-on: ubuntu-latest - container: node:16-buster + container: node:lts-bullseye steps: - name: Checkout Repository uses: actions/checkout@v4 @@ -71,7 +71,7 @@ jobs: needs: build name: Release runs-on: ubuntu-latest - container: node:16-buster + container: node:lts-bullseye steps: # Dependencies - name: Install Go @@ -87,7 +87,7 @@ jobs: - name: Create Release uses: https://gitea.com/actions/release-action@main with: - files: ./out + files: ./out api_key: ${{ secrets.RELEASE_TOKEN }} title: v${{ github.ref_name }} body: "[View Changelog](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/src/branch/master/docs/CHANGELOG.md)" diff --git a/docs/COMMAND_LINE.md b/docs/COMMAND_LINE.md index 8f322bc3..4e1a28a5 100644 --- a/docs/COMMAND_LINE.md +++ b/docs/COMMAND_LINE.md @@ -8,6 +8,9 @@ If you run MCPI-Reborn with ``--version`` it will print its version to ``stdout` ### ``--debug`` This sets ``MCPI_DEBUG``. +### ``--copy-sdk`` +This extracts the modding SDK and immediately exits. (This allows the SDK to be extracted without starting the game.) + ### Client Mode Only #### ``--print-available-feature-flags`` diff --git a/example-mods/chat-commands/CMakeLists.txt b/example-mods/chat-commands/CMakeLists.txt index b2c5cfe1..90a8e939 100644 --- a/example-mods/chat-commands/CMakeLists.txt +++ b/example-mods/chat-commands/CMakeLists.txt @@ -14,4 +14,4 @@ include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cma # Build add_library(chat-commands SHARED chat-commands.cpp) -target_link_libraries(chat-commands mods-headers reborn-patch symbols chat misc) +target_link_libraries(chat-commands mods reborn-patch symbols) diff --git a/example-mods/expanded-creative/CMakeLists.txt b/example-mods/expanded-creative/CMakeLists.txt index c317ec4a..524b11da 100644 --- a/example-mods/expanded-creative/CMakeLists.txt +++ b/example-mods/expanded-creative/CMakeLists.txt @@ -14,4 +14,4 @@ include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cma # Build add_library(expanded-creative SHARED expanded-creative.cpp) -target_link_libraries(expanded-creative mods-headers reborn-patch symbols misc) +target_link_libraries(expanded-creative mods reborn-patch symbols) diff --git a/example-mods/recipes/CMakeLists.txt b/example-mods/recipes/CMakeLists.txt index 9e39aed7..b1be8ad9 100644 --- a/example-mods/recipes/CMakeLists.txt +++ b/example-mods/recipes/CMakeLists.txt @@ -14,4 +14,4 @@ include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-client/sdk/sdk.cma # Build add_library(recipes SHARED recipes.cpp) -target_link_libraries(recipes mods-headers reborn-util symbols misc) +target_link_libraries(recipes mods reborn-util symbols) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 99386cff..ba796d34 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1,7 +1,7 @@ project(launcher) # Launcher -add_executable(launcher src/bootstrap.c src/patchelf.cpp src/util.c src/crash-report.c) +add_executable(launcher src/bootstrap.c src/patchelf.cpp src/util.c src/crash-report.c src/sdk.c src/mods.c) if(MCPI_SERVER_MODE) target_sources(launcher PRIVATE src/server/launcher.c) else() diff --git a/launcher/src/bootstrap.c b/launcher/src/bootstrap.c index b5cc9313..e5e9ee41 100644 --- a/launcher/src/bootstrap.c +++ b/launcher/src/bootstrap.c @@ -1,13 +1,5 @@ #define _FILE_OFFSET_BITS 64 -#include -#include -#include -#include -#include -#include -#include - #include #include "util.h" @@ -15,77 +7,6 @@ #include "patchelf.h" #include "crash-report.h" -// Get All Mods In Folder -static void load(char **ld_preload, char *folder) { - int folder_name_length = strlen(folder); - // Retry Until Successful - while (1) { - // Open Folder - DIR *dp = opendir(folder); - if (dp != NULL) { - // Loop Through Folder - struct dirent *entry = NULL; - errno = 0; - while (1) { - errno = 0; - entry = readdir(dp); - if (entry != NULL) { - // Check If File Is Regular - if (entry->d_type == DT_REG) { - // Get Full Name - int name_length = strlen(entry->d_name); - int total_length = folder_name_length + name_length; - char name[total_length + 1]; - - // Concatenate Folder Name And File Name - for (int i = 0; i < folder_name_length; i++) { - name[i] = folder[i]; - } - for (int i = 0; i < name_length; i++) { - name[folder_name_length + i] = entry->d_name[i]; - } - // Add Terminator - name[total_length] = '\0'; - - // Check If File Is Accessible - int result = access(name, R_OK); - if (result == 0) { - // Add To LD_PRELOAD - string_append(ld_preload, "%s%s", *ld_preload == NULL ? "" : ":", name); - } else if (result == -1 && errno != 0) { - // Fail - WARN("Unable To Access: %s: %s", name, strerror(errno)); - errno = 0; - } - } - } else if (errno != 0) { - // Error Reading Contents Of Folder - ERR("Error Reading Directory: %s: %s", folder, strerror(errno)); - } else { - // Done! - break; - } - } - // Close Folder - closedir(dp); - - // Exit Function - return; - } else if (errno == ENOENT) { - // Folder Doesn't Exists, Attempt Creation - int ret = mkdir(folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - if (ret != 0) { - // Unable To Create Folder - ERR("Error Creating Directory: %s: %s", folder, strerror(errno)); - } - // Continue Retrying - } else { - // Unable To Open Folder - ERR("Error Opening Directory: %s: %s", folder, strerror(errno)); - } - } -} - #define MCPI_BINARY "minecraft-pi" #define QEMU_BINARY "qemu-arm" @@ -182,11 +103,11 @@ void pre_bootstrap(int argc, char *argv[]) { set_and_print_env("GTK_THEME", "Adwaita:dark"); #endif - // Get Binary Directory - char *binary_directory = get_binary_directory(); - // Configure PATH { + // Get Binary Directory + char *binary_directory = get_binary_directory(); + // Add Library Directory char *new_path = NULL; safe_asprintf(&new_path, "%s/bin", binary_directory); @@ -200,10 +121,21 @@ void pre_bootstrap(int argc, char *argv[]) { // Set And Free set_and_print_env("PATH", new_path); free(new_path); + + // Free Binary Directory + free(binary_directory); } - // Free Binary Directory - free(binary_directory); + // --copy-sdk + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--copy-sdk") == 0) { + char *binary_directory = get_binary_directory(); + copy_sdk(binary_directory, 0); + free(binary_directory); + fflush(stdout); + exit(EXIT_SUCCESS); + } + } // Setup Crash Reports setup_crash_report(); @@ -242,56 +174,6 @@ void pre_bootstrap(int argc, char *argv[]) { print_debug_information(); } -// Copy SDK Into ~/.minecraft-pi -#define HOME_SUBDIRECTORY_FOR_SDK HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk" -static void copy_sdk(char *binary_directory) { - // Ensure SDK Directory - { - char *sdk_path = NULL; - safe_asprintf(&sdk_path, "%s" HOME_SUBDIRECTORY_FOR_SDK, getenv("HOME")); - const char *const command[] = {"mkdir", "-p", sdk_path, NULL}; - run_simple_command(command, "Unable To Create SDK Directory"); - } - - // Lock File - char *lock_file_path = NULL; - safe_asprintf(&lock_file_path, "%s" HOME_SUBDIRECTORY_FOR_SDK "/.lock", getenv("HOME")); - int lock_file_fd = lock_file(lock_file_path); - - // Output Directory - char *output = NULL; - safe_asprintf(&output, "%s" HOME_SUBDIRECTORY_FOR_SDK "/" MCPI_SDK_DIR, getenv("HOME")); - // Source Directory - char *source = NULL; - safe_asprintf(&source, "%s/sdk/.", binary_directory); - - // Clean - { - const char *const command[] = {"rm", "-rf", output, NULL}; - run_simple_command(command, "Unable To Clean SDK Output Directory"); - } - - // Make Directory - { - const char *const command[] = {"mkdir", "-p", output, NULL}; - run_simple_command(command, "Unable To Create SDK Output Directory"); - } - - // Copy - { - const char *const command[] = {"cp", "-ar", source, output, NULL}; - run_simple_command(command, "Unable To Copy SDK"); - } - - // Free - free(output); - free(source); - - // Unlock File - unlock_file(lock_file_path, lock_file_fd); - free(lock_file_path); -} - // Bootstrap void bootstrap(int argc, char *argv[]) { INFO("Configuring Game..."); @@ -301,7 +183,7 @@ void bootstrap(int argc, char *argv[]) { DEBUG("Binary Directory: %s", binary_directory); // Copy SDK - copy_sdk(binary_directory); + copy_sdk(binary_directory, 1); // Set MCPI_REBORN_ASSETS_PATH { @@ -432,44 +314,7 @@ void bootstrap(int argc, char *argv[]) { set_and_print_env("MCPI_NATIVE_LD_PRELOAD", host_ld_preload); // ARM Components - { - // Prepare - char *preload = NULL; - - // ~/.minecraft-pi/mods - { - // Get Mods Folder - char *mods_folder = NULL; - safe_asprintf(&mods_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA "/mods/", getenv("HOME")); - // Load Mods From ./mods - load(&preload, mods_folder); - // Free Mods Folder - free(mods_folder); - } - - // Built-In Mods - { - // Get Mods Folder - char *mods_folder = NULL; - safe_asprintf(&mods_folder, "%s/mods/", binary_directory); - // Load Mods From ./mods - load(&preload, mods_folder); - // Free Mods Folder - free(mods_folder); - } - - // Add LD_PRELOAD - { - char *value = getenv("LD_PRELOAD"); - if (value != NULL && strlen(value) > 0) { - string_append(&preload, ":%s", value); - } - } - - // Set - set_and_print_env("MCPI_ARM_LD_PRELOAD", preload); - free(preload); - } + bootstrap_mods(binary_directory); } // Free Binary Directory diff --git a/launcher/src/bootstrap.h b/launcher/src/bootstrap.h index 6afe6372..82452038 100644 --- a/launcher/src/bootstrap.h +++ b/launcher/src/bootstrap.h @@ -6,6 +6,8 @@ extern "C" { void pre_bootstrap(int argc, char *argv[]); void bootstrap(int argc, char *argv[]); +void copy_sdk(char *binary_directory, int log_with_debug); +void bootstrap_mods(char *binary_directory); #ifdef __cplusplus } diff --git a/launcher/src/mods.c b/launcher/src/mods.c new file mode 100644 index 00000000..418ab9ae --- /dev/null +++ b/launcher/src/mods.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "bootstrap.h" + +// Get All Mods In Folder +static void load(char **ld_preload, const char *folder) { + int folder_name_length = strlen(folder); + // Open Folder + DIR *dp = opendir(folder); + if (dp != NULL) { + // Loop Through Folder + struct dirent *entry = NULL; + errno = 0; + while (1) { + errno = 0; + entry = readdir(dp); + if (entry != NULL) { + // Check If File Is Regular + if (entry->d_type == DT_REG) { + // Get Full Name + int name_length = strlen(entry->d_name); + int total_length = folder_name_length + name_length; + char name[total_length + 1]; + + // Concatenate Folder Name And File Name + for (int i = 0; i < folder_name_length; i++) { + name[i] = folder[i]; + } + for (int i = 0; i < name_length; i++) { + name[folder_name_length + i] = entry->d_name[i]; + } + // Add Terminator + name[total_length] = '\0'; + + // Check If File Is Accessible + int result = access(name, R_OK); + if (result == 0) { + // Add To LD_PRELOAD + string_append(ld_preload, "%s%s", *ld_preload == NULL ? "" : ":", name); + } else if (result == -1 && errno != 0) { + // Fail + WARN("Unable To Access: %s: %s", name, strerror(errno)); + errno = 0; + } + } + } else if (errno != 0) { + // Error Reading Contents Of Folder + ERR("Error Reading Directory: %s: %s", folder, strerror(errno)); + } else { + // Done! + break; + } + } + // Close Folder + closedir(dp); + } else if (errno == ENOENT) { + // Folder Doesn't Exist + } else { + // Unable To Open Folder + ERR("Error Opening Directory: %s: %s", folder, strerror(errno)); + } +} + +// Bootstrap Mods +void bootstrap_mods(char *binary_directory) { + // Prepare + char *preload = NULL; + + // ~/.minecraft-pi/mods + { + // Get Mods Folder + char *mods_folder = NULL; + safe_asprintf(&mods_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA "/mods/", getenv("HOME")); + // Load Mods From ./mods + load(&preload, mods_folder); + // Free Mods Folder + free(mods_folder); + } + + // Built-In Mods + { + // Get Mods Folder + char *mods_folder = NULL; + safe_asprintf(&mods_folder, "%s/mods/", binary_directory); + // Load Mods From ./mods + load(&preload, mods_folder); + // Free Mods Folder + free(mods_folder); + } + + // Add LD_PRELOAD + { + char *value = getenv("LD_PRELOAD"); + if (value != NULL && strlen(value) > 0) { + string_append(&preload, ":%s", value); + } + } + + // Set + set_and_print_env("MCPI_ARM_LD_PRELOAD", preload); + free(preload); +} diff --git a/launcher/src/sdk.c b/launcher/src/sdk.c new file mode 100644 index 00000000..2547a904 --- /dev/null +++ b/launcher/src/sdk.c @@ -0,0 +1,67 @@ +#include + +#include "bootstrap.h" +#include "util.h" + +// Log +#define LOG(is_debug, ...) \ + { \ + if (is_debug) { \ + DEBUG(__VA_ARGS__); \ + } else { \ + INFO(__VA_ARGS__); \ + } \ + } + +// Copy SDK Into ~/.minecraft-pi +#define HOME_SUBDIRECTORY_FOR_SDK HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk" +void copy_sdk(char *binary_directory, int log_with_debug) { + // Ensure SDK Directory + { + char *sdk_path = NULL; + safe_asprintf(&sdk_path, "%s" HOME_SUBDIRECTORY_FOR_SDK, getenv("HOME")); + const char *const command[] = {"mkdir", "-p", sdk_path, NULL}; + run_simple_command(command, "Unable To Create SDK Directory"); + } + + // Lock File + char *lock_file_path = NULL; + safe_asprintf(&lock_file_path, "%s" HOME_SUBDIRECTORY_FOR_SDK "/.lock", getenv("HOME")); + int lock_file_fd = lock_file(lock_file_path); + + // Output Directory + char *output = NULL; + safe_asprintf(&output, "%s" HOME_SUBDIRECTORY_FOR_SDK "/" MCPI_SDK_DIR, getenv("HOME")); + // Source Directory + char *source = NULL; + safe_asprintf(&source, "%s/sdk/.", binary_directory); + + // Clean + { + const char *const command[] = {"rm", "-rf", output, NULL}; + run_simple_command(command, "Unable To Clean SDK Output Directory"); + } + + // Make Directory + { + const char *const command[] = {"mkdir", "-p", output, NULL}; + run_simple_command(command, "Unable To Create SDK Output Directory"); + } + + // Copy + { + const char *const command[] = {"cp", "-ar", source, output, NULL}; + run_simple_command(command, "Unable To Copy SDK"); + } + + // Log + LOG(log_with_debug, "Copied SDK To: %s", output); + + // Free + free(output); + free(source); + + // Unlock File + unlock_file(lock_file_path, lock_file_fd); + free(lock_file_path); +} diff --git a/mods/CMakeLists.txt b/mods/CMakeLists.txt index b9dac354..2931a922 100644 --- a/mods/CMakeLists.txt +++ b/mods/CMakeLists.txt @@ -1,141 +1,123 @@ project(mods) -## Headers -add_library(mods-headers INTERFACE) +# Common Sources +set(SRC + # compat + src/compat/compat.c + src/compat/egl.c + src/compat/x11.c + src/compat/bcm_host.c + # readdir + src/readdir/readdir.c + # feature + src/feature/feature.c + # version + src/version/version.cpp + # chat + src/chat/chat.cpp + src/chat/ui.c + # creative + src/creative/creative.cpp + # game-mode + src/game-mode/game-mode.c + src/game-mode/ui.cpp + # override + src/override/override.c + # death + src/death/death.cpp + # misc + src/misc/misc.c + src/misc/misc.cpp + src/misc/logging.cpp + src/misc/api.cpp + # options + src/options/options.c + src/options/options.cpp + # bucket + src/bucket/bucket.cpp + # home + src/home/home.c + # test + src/test/test.c + # init + src/init/init.c +) + +# Server-Only Sources +if(MCPI_SERVER_MODE) + list(APPEND SRC + # server + src/server/server.cpp + src/server/server_properties.cpp + ) +else() + list(APPEND SRC + # multiplayer + src/multiplayer/multiplayer.cpp + # benchmark + src/benchmark/benchmark.cpp + ) +endif() + +# Headless-Only Sources +if(MCPI_HEADLESS_MODE) + list(APPEND SRC + # textures + src/textures/headless.cpp + ) +else() + list(APPEND SRC + # sound + src/sound/sound.cpp + src/sound/repository.cpp + # camera + src/camera/camera.cpp + # input + src/input/input.cpp + src/input/bow.c + src/input/attack.c + src/input/toggle.c + src/input/misc.c + src/input/drop.cpp + src/input/crafting.cpp + # sign + src/sign/sign.cpp + # touch + src/touch/touch.cpp + # atlas + src/atlas/atlas.cpp + # title-screen + src/title-screen/title-screen.cpp + # skin + src/skin/skin.cpp + src/skin/loader.cpp + # screenshot + src/screenshot/screenshot.c + # textures + src/textures/textures.cpp + ) +endif() + +# Build +add_library(mods SHARED ${SRC}) + +# Install +install(TARGETS mods DESTINATION "${MCPI_INSTALL_DIR}/mods") +# SDK +install(TARGETS mods EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}") + +# Dependencies +target_link_libraries(mods symbols reborn-patch media-layer-core dl pthread) +if(NOT MCPI_HEADLESS_MODE) + target_link_libraries(mods stb_image) +endif() + +# Headers target_include_directories( - mods-headers - INTERFACE + mods + PUBLIC "$" "$" ) -target_link_libraries(mods-headers INTERFACE symbols) # SDK -install(TARGETS mods-headers EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}") install(DIRECTORY "include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/mods") - -## Mods - -add_library(compat SHARED src/compat/compat.c src/compat/egl.c src/compat/x11.c src/compat/bcm_host.c) -target_link_libraries(compat mods-headers reborn-patch media-layer-core) -if(NOT MCPI_HEADLESS_MODE) - target_link_libraries(compat screenshot input sign chat home dl) -endif() - -add_library(readdir SHARED src/readdir/readdir.c) - -add_library(feature SHARED src/feature/feature.c) -target_link_libraries(feature mods-headers reborn-patch) - -add_library(version SHARED src/version/version.cpp) -target_link_libraries(version mods-headers reborn-patch symbols) - -add_library(chat SHARED src/chat/chat.cpp src/chat/ui.c) -target_link_libraries(chat mods-headers reborn-patch symbols feature) -if(NOT MCPI_HEADLESS_MODE) - target_link_libraries(chat input media-layer-core pthread) -endif() - -add_library(creative SHARED src/creative/creative.cpp) -target_link_libraries(creative mods-headers reborn-patch symbols feature misc) - -add_library(game-mode SHARED src/game-mode/game-mode.c src/game-mode/ui.cpp) -target_link_libraries(game-mode mods-headers reborn-patch symbols feature) -if(NOT MCPI_SERVER_MODE) - target_link_libraries(game-mode pthread media-layer-core) -endif() - -if(MCPI_SERVER_MODE) - add_library(server SHARED src/server/server.cpp src/server/server_properties.cpp) - target_link_libraries(server mods-headers reborn-patch symbols feature home misc compat dl media-layer-core pthread) -else() - add_library(multiplayer SHARED src/multiplayer/multiplayer.cpp) - target_link_libraries(multiplayer mods-headers reborn-patch symbols home feature) - - add_library(benchmark SHARED src/benchmark/benchmark.cpp) - target_link_libraries(benchmark mods-headers reborn-patch symbols compat misc media-layer-core) -endif() - -if(NOT MCPI_HEADLESS_MODE) - add_library(sound SHARED src/sound/sound.cpp src/sound/repository.cpp) - target_link_libraries(sound mods-headers reborn-patch symbols feature override media-layer-core) - - add_library(camera SHARED src/camera/camera.cpp) - target_link_libraries(camera mods-headers reborn-patch symbols feature home screenshot) - - add_library(input SHARED src/input/input.cpp src/input/bow.c src/input/attack.c src/input/toggle.c src/input/misc.c src/input/drop.cpp src/input/crafting.cpp) - target_link_libraries(input mods-headers reborn-patch symbols creative feature misc media-layer-core) - - add_library(sign SHARED src/sign/sign.cpp) - target_link_libraries(sign mods-headers reborn-patch symbols feature input media-layer-core) - - add_library(touch SHARED src/touch/touch.cpp) - target_link_libraries(touch mods-headers reborn-patch symbols feature) - - add_library(atlas SHARED src/atlas/atlas.cpp) - target_link_libraries(atlas mods-headers reborn-patch symbols feature media-layer-core) - - add_library(title-screen SHARED src/title-screen/title-screen.cpp) - target_link_libraries(title-screen mods-headers reborn-patch symbols feature compat) - - add_library(skin SHARED src/skin/skin.cpp src/skin/loader.cpp) - target_link_libraries(skin mods-headers reborn-patch symbols feature misc textures media-layer-core stb_image) - - add_library(screenshot SHARED src/screenshot/screenshot.c) - target_link_libraries(screenshot mods-headers reborn-util media-layer-core stb_image) -endif() - -if(NOT MCPI_HEADLESS_MODE) - add_library(textures SHARED src/textures/textures.cpp) -else() - add_library(textures SHARED src/textures/headless.cpp) -endif() -target_link_libraries(textures mods-headers reborn-patch symbols) -if(NOT MCPI_HEADLESS_MODE) - target_link_libraries(textures media-layer-core feature misc stb_image) -endif() - -add_library(override SHARED src/override/override.c) -target_link_libraries(override mods-headers reborn-patch symbols dl home) - -add_library(death SHARED src/death/death.cpp) -target_link_libraries(death mods-headers reborn-patch symbols feature) - -add_library(misc SHARED src/misc/misc.c src/misc/misc.cpp src/misc/logging.cpp src/misc/api.cpp) -target_link_libraries(misc mods-headers reborn-patch symbols media-layer-core feature) - -add_library(options SHARED src/options/options.c src/options/options.cpp) -target_link_libraries(options mods-headers reborn-patch symbols feature home) - -add_library(bucket SHARED src/bucket/bucket.cpp) -target_link_libraries(bucket mods-headers reborn-patch symbols feature misc) - -add_library(home SHARED src/home/home.c) -target_link_libraries(home mods-headers reborn-patch symbols) - -add_library(test SHARED src/test/test.c) -target_link_libraries(test mods-headers reborn-patch home) - -add_library(init SHARED src/init/init.c) -target_link_libraries(init symbols mods-headers reborn-util compat game-mode misc death options chat creative bucket textures home version test media-layer-core) -if(MCPI_SERVER_MODE) - target_link_libraries(init server) -else() - target_link_libraries(init multiplayer benchmark) -endif() -if(NOT MCPI_HEADLESS_MODE) - target_link_libraries(init sound camera input sign touch atlas title-screen skin) -endif() - -## Install Mods -set(MODS_TO_INSTALL init compat readdir feature game-mode misc override death options chat creative bucket textures home version test) -if(MCPI_SERVER_MODE) - list(APPEND MODS_TO_INSTALL server) -else() - list(APPEND MODS_TO_INSTALL multiplayer benchmark) -endif() -if(NOT MCPI_HEADLESS_MODE) - list(APPEND MODS_TO_INSTALL sound camera input sign touch atlas title-screen skin screenshot) -endif() -install(TARGETS ${MODS_TO_INSTALL} DESTINATION "${MCPI_INSTALL_DIR}/mods") -# SDK -install(TARGETS ${MODS_TO_INSTALL} EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")