Compare commits

..

3 Commits

Author SHA1 Message Date
3de52ceab3 Add Sign To Expanded Creative Inventory 2022-10-31 19:27:17 -04:00
51c12db49c Rename Package 2022-10-31 19:27:17 -04:00
a30eeba2fd Port To v0.1.0 2022-10-31 19:27:17 -04:00
609 changed files with 13095 additions and 19432 deletions

View File

@ -1,136 +0,0 @@
name: 'CI'
on:
push:
branches:
- master
tags:
- '*'
- '!flatpak'
# Jobs
jobs:
# Build Project
build:
strategy:
fail-fast: false
matrix:
arch:
- AMD64
- ARM64
- ARMHF
name: Build
runs-on: ubuntu-latest
container: node:lts-bullseye
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: true
# Dependencies
- name: Install Dependencies
run: ./scripts/install-dependencies.mjs build ${{ matrix.arch }}
# Build
- name: Build
run: ./scripts/build.mjs appimage ${{ matrix.arch }}
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.arch }}
path: ./out/*.AppImage*
if-no-files-found: error
# Test Project
test:
needs: build
strategy:
fail-fast: false
matrix:
mode:
- Client
- Server
arch:
- AMD64
- ARM64
- ARMHF
name: Test
runs-on: ${{ startsWith(matrix.arch, 'ARM') && 'raspberry-pi' || 'ubuntu-latest' }}
container: node:lts-bullseye
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: false
# Dependencies
- name: Install Dependencies
run: ./scripts/install-dependencies.mjs test ${{ matrix.arch }}
# Download Artifact
- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: ${{ matrix.arch }}
path: out
# Test
- name: Test
run: ./scripts/test.sh ${{ matrix.mode }} ${{ matrix.arch }}
# Example Mods
example-mods:
needs: build
name: Build Example Mods
runs-on: ubuntu-latest
container: node:lts-bullseye
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: false
# Dependencies
- name: Install Dependencies
run: ./scripts/install-dependencies.mjs sdk amd64
# SDK
- name: Download SDK
uses: actions/download-artifact@v3
with:
name: AMD64
path: out
- name: Extract SDK
run: |
./scripts/fix-appimage-for-docker.sh ./out/*.AppImage
chmod +x ./out/*.AppImage
./out/*.AppImage --appimage-extract-and-run --copy-sdk
# Build Example Mods
- name: Build Example Mods
run: ./example-mods/build.sh
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: Example Mods
path: ./example-mods/out/*
if-no-files-found: error
# Create Release
release:
if: startsWith(github.ref, 'refs/tags/')
needs:
- build
- test
- example-mods
name: Release
runs-on: ubuntu-latest
container: node:lts-bullseye
steps:
# Dependencies
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: '>=1.20.1'
# Download Artifacts
- name: Download Artifacts
uses: actions/download-artifact@v3
with:
path: out
# Create Release
- name: Create Release
uses: https://gitea.com/actions/release-action@main
with:
files: ./out/*/*.AppImage*
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)'

4
.gitignore vendored
View File

@ -12,7 +12,3 @@
/*.AppImage
/core*
/qemu_*
/example-mods/out
/.testing-tmp
/cmake-build-*
/.idea

37
.gitmodules vendored
View File

@ -1,29 +1,20 @@
[submodule "dependencies/libpng/src"]
path = dependencies/libpng/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/libpng.git
[submodule "dependencies/zlib/src"]
path = dependencies/libpng/zlib/src
url = https://github.com/madler/zlib.git
ignore = dirty
[submodule "dependencies/glfw/src"]
path = dependencies/glfw/src
path = media-layer/core/dependencies/glfw/src
url = https://github.com/glfw/glfw.git
[submodule "dependencies/zenity/src"]
path = dependencies/zenity/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/zenity.git
[submodule "dependencies/LIEF/src"]
path = dependencies/LIEF/src
url = https://github.com/lief-project/LIEF.git
[submodule "dependencies/stb_image/include"]
path = dependencies/stb_image/include
url = https://github.com/nothings/stb.git
[submodule "dependencies/utf8cpp/src"]
path = dependencies/utf8cpp/src
url = https://github.com/nemtrif/utfcpp.git
[submodule "archives"]
path = archives
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/archives.git
shallow = true
[submodule "dependencies/symbol-processor/src"]
path = dependencies/symbol-processor/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/symbol-processor.git
[submodule "dependencies/runtime/src"]
path = dependencies/runtime/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/runtime.git
[submodule "dependencies/imgui/src"]
path = dependencies/imgui/src
url = https://github.com/ocornut/imgui.git
[submodule "dependencies/qemu/src"]
path = dependencies/qemu/src
url = https://gitlab.com/qemu-project/qemu.git
ignore = dirty
[submodule "dependencies/imgui/glad/src"]
path = dependencies/imgui/glad/src
url = https://github.com/Dav1dde/glad.git

View File

@ -1,55 +1,139 @@
cmake_minimum_required(VERSION 3.25.0)
cmake_minimum_required(VERSION 3.16.0)
# Avoid Warning About DOWNLOAD_EXTRACT_TIMESTAMP
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24.0)
cmake_policy(SET CMP0135 NEW)
# Core Options
include(cmake/options/core-options.cmake)
# Utility Functions
include(cmake/util/util.cmake)
endif()
# Build Mode
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(IS_MULTI_CONFIG)
force_set(CMAKE_CONFIGURATION_TYPES "Release;Debug" STRING)
set(FORCE_BUILD_TYPE "")
elseif(NOT DEFINED CMAKE_BUILD_TYPE)
set(FORCE_BUILD_TYPE "Release")
set(MCPI_BUILD_MODE "native" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code")
set_property(CACHE MCPI_BUILD_MODE PROPERTY STRINGS "arm" "native")
if(MCPI_BUILD_MODE STREQUAL "arm")
set(BUILD_ARM_COMPONENTS TRUE)
set(BUILD_NATIVE_COMPONENTS FALSE)
elseif(MCPI_BUILD_MODE STREQUAL "native")
set(BUILD_ARM_COMPONENTS FALSE)
set(BUILD_NATIVE_COMPONENTS TRUE)
else()
message(FATAL_ERROR "Invalid Mode")
endif()
if(DEFINED FORCE_BUILD_TYPE)
force_set(CMAKE_BUILD_TYPE "${FORCE_BUILD_TYPE}" STRING)
# Specify Options
option(MCPI_IS_MIXED_BUILD "Whether The Architecture-Independent And ARM Code Are Different Architecture" FALSE)
option(MCPI_OPEN_SOURCE_ONLY "Only Install Open-Source Code (Will Result In Broken Install)" FALSE)
option(MCPI_IS_APPIMAGE_BUILD "AppImage Build" FALSE)
# Server/Headless Builds
option(MCPI_SERVER_MODE "Server Mode" FALSE)
option(MCPI_HEADLESS_MODE "Headless Mode" ${MCPI_SERVER_MODE})
# Media Layer
if(MCPI_HEADLESS_MODE)
set(DEFAULT_USE_MEDIA_LAYER_PROXY FALSE)
else()
set(DEFAULT_USE_MEDIA_LAYER_PROXY ${MCPI_IS_MIXED_BUILD})
endif()
option(MCPI_USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" ${DEFAULT_USE_MEDIA_LAYER_PROXY})
if(NOT MCPI_HEADLESS_MODE)
option(MCPI_USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" TRUE)
endif()
# App ID
set(DEFAULT_APP_ID "com.thebrokenrail.MCPIRebornLegacy")
if(MCPI_SERVER_MODE)
string(APPEND DEFAULT_APP_ID "Server")
else()
string(APPEND DEFAULT_APP_ID "Client")
endif()
set(MCPI_APP_ID "${DEFAULT_APP_ID}" CACHE STRING "App ID")
# App Title
set(MCPI_APP_BASE_TITLE "Minecraft: Pi Edition: Reborn Legacy" CACHE STRING "Base App Title")
set(DEFAULT_APP_TITLE "${MCPI_APP_BASE_TITLE}")
if(MCPI_SERVER_MODE)
string(APPEND DEFAULT_APP_TITLE " (Server)")
else()
string(APPEND DEFAULT_APP_TITLE " (Client)")
endif()
set(MCPI_APP_TITLE "${DEFAULT_APP_TITLE}" CACHE STRING "App Title")
# Specify Variant Name
set(MCPI_VARIANT_NAME "minecraft-pi-reborn-legacy")
if(MCPI_SERVER_MODE)
string(APPEND MCPI_VARIANT_NAME "-server")
else()
string(APPEND MCPI_VARIANT_NAME "-client")
endif()
# Specify Installation Paths
set(MCPI_INSTALL_DIR "lib/${MCPI_VARIANT_NAME}")
set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin")
set(MCPI_LEGAL_DIR "${MCPI_INSTALL_DIR}/legal") # For Software Licenses
set(MCPI_SDK_DIR "${MCPI_INSTALL_DIR}/sdk")
set(MCPI_SDK_LIB_DIR "${MCPI_SDK_DIR}/lib")
set(MCPI_SDK_INCLUDE_DIR "${MCPI_SDK_DIR}/include")
# Library Directory
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
if(BUILD_ARM_COMPONENTS)
string(APPEND MCPI_LIB_DIR "/arm")
elseif(BUILD_NATIVE_COMPONENTS)
string(APPEND MCPI_LIB_DIR "/native")
endif()
# Share Directory
set(MCPI_SHARE_DIR "share")
if(MCPI_IS_APPIMAGE_BUILD)
string(PREPEND MCPI_SHARE_DIR "usr/")
endif()
# Build Mode
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
# Prebuilt ARMHF Toolchain
option(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN "Whether To Use A Prebuilt ARMHF Toolchain For Building ARM Components" ${MCPI_IS_MIXED_BUILD})
if(BUILD_ARM_COMPONENTS AND MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
include(cmake/prebuilt-armhf-toolchain.cmake)
endif()
# Start Project
project(minecraft-pi-reborn)
# Utility Functions
include(cmake/util.cmake)
# Sanity Checks
string(CONCAT ARM_SANITY_CHECK
"include(CheckSymbolExists)\n"
"check_symbol_exists(\"__arm__\" \"\" IS_ARM_TARGETING)\n"
)
if(BUILD_ARM_COMPONENTS)
string(APPEND ARM_SANITY_CHECK
"if(NOT IS_ARM_TARGETING)\n"
" message(FATAL_ERROR \"ARM-Targeting Compiler Required\")\n"
"endif()\n"
)
set(IS_ARM_TARGETING FALSE)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l")
set(IS_ARM_TARGETING TRUE)
endif()
if(BUILD_NATIVE_COMPONENTS AND NOT IS_ARM_TARGETING AND NOT MCPI_IS_MIXED_BUILD)
message(FATAL_ERROR "Project is configured as a mixed-buld, but MCPI_IS_MIXED_BUILD is disabled.")
endif()
if(BUILD_ARM_COMPONENTS AND NOT IS_ARM_TARGETING)
message(FATAL_ERROR "ARM-Targeting Compiler Required")
endif()
cmake_language(EVAL CODE "${ARM_SANITY_CHECK}")
# Extra Options
include(cmake/options/extra-options.cmake)
# Paths
include(cmake/options/paths.cmake)
# Specify Default Installation Prefix
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(DEFAULT_PREFIX "/usr")
if(MCPI_IS_APPIMAGE_BUILD)
set(DEFAULT_PREFIX "/")
endif()
set(CMAKE_INSTALL_PREFIX "${DEFAULT_PREFIX}" CACHE PATH "" FORCE)
set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT FALSE)
endif()
# Required Compile Flags
set(RELEASE_MODE_GENERATOR "\$<CONFIG:Release>")
string(CONCAT COMPILE_FLAGS_SETUP
# Optimizations
"add_compile_options(\"\$<IF:${RELEASE_MODE_GENERATOR},-O3,-g>\")\n"
"add_link_options(\"\$<${RELEASE_MODE_GENERATOR}:-s>\")\n"
"if(CMAKE_BUILD_TYPE STREQUAL \"Release\")\n"
" add_compile_options(-O3 -s)\n"
"else()\n"
" add_compile_options(-g)\n"
"endif()\n"
# PIC
"set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)\n"
@ -60,31 +144,19 @@ string(CONCAT COMPILE_FLAGS_SETUP
# C Standard
"add_definitions(-D_GNU_SOURCE)\n"
"set(CMAKE_C_STANDARD 99)\n"
"set(CMAKE_CXX_STANDARD 20)\n"
"set(CMAKE_CXX_STANDARD 11)\n"
# Skip RPath
"set(CMAKE_SKIP_BUILD_RPATH TRUE)\n"
# Always Build Shared Libraries
"set(BUILD_SHARED_LIBS TRUE CACHE BOOL \"\" FORCE)\n"
"set(CMAKE_SKIP_BUILD_RPATH TRUE)"
)
if(BUILD_ARM_COMPONENTS)
string(APPEND COMPILE_FLAGS_SETUP
# Disable C++11 String ABI
"add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)\n"
)
endif()
cmake_language(EVAL CODE "${COMPILE_FLAGS_SETUP}")
# Build Dependencies
add_subdirectory(dependencies)
# Fast Math
add_compile_options(-ffast-math)
# Warnings
add_compile_options(-Wall -Wextra -Werror -Wpointer-arith -Wshadow -Wnull-dereference)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
if(CMAKE_C_COMPILER_ID STREQUAL \"GNU\")
# Prevents False Positives
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 10.0)
add_compile_options(-Wno-stringop-overflow)
@ -94,6 +166,18 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
endif()
endif()
# Buld Dependencies
add_subdirectory(dependencies)
# Version
set_property(
DIRECTORY
APPEND
PROPERTY CMAKE_CONFIGURE_DEPENDS VERSION
)
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" MCPI_VERSION)
file(TIMESTAMP "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" MCPI_VERSION_DATE "%Y-%m-%d" UTC)
# Build libreborn
add_subdirectory(libreborn)
@ -120,93 +204,16 @@ if(BUILD_NATIVE_COMPONENTS)
add_subdirectory(images)
endif()
# Install Prebuilt ARMHF Toolchain Sysroot
if(BUILD_NATIVE_COMPONENTS AND MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
install_arm_sysroot()
endif()
# Install SDK
if(BUILD_ARM_COMPONENTS)
install(EXPORT sdk DESTINATION "${MCPI_SDK_DIR}" FILE "sdk-targets.cmake")
install(EXPORT sdk DESTINATION "${MCPI_SDK_DIR}" FILE "sdk-targets.cmake" EXPORT_LINK_INTERFACE_LIBRARIES)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake"
# Sanity Check
"${ARM_SANITY_CHECK}"
# Compile Flags
"${COMPILE_FLAGS_SETUP}"
"${COMPILE_FLAGS_SETUP}\n"
# Log
"message(STATUS \"Using Reborn SDK v${MCPI_VERSION}\")\n"
"message(STATUS \"Using Reborn Legacy SDK v${MCPI_VERSION}\")\n"
# Include Targets
"include(\"\${CMAKE_CURRENT_LIST_DIR}/sdk-targets.cmake\")\n"
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake" DESTINATION "${MCPI_SDK_DIR}")
# Calculate Hash Of SDK
string(CONCAT SDK_HASH_SCRIPT
# Prepare
"set(dir \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${MCPI_SDK_DIR}\")\n"
"set(out \"\${dir}/.hash\")\n"
# Calculate Hashes
"set(content \"\")\n"
"file(GLOB_RECURSE files LIST_DIRECTORIES FALSE \"\${dir}/*\")\n"
"foreach(file IN LISTS files)\n"
" file(SHA256 \"\${file}\" hash)\n"
" cmake_path(RELATIVE_PATH file BASE_DIRECTORY \"\${dir}\")\n"
" string(APPEND content \"\${hash} \${file}\\n\")\n"
"endforeach()\n"
# Write File
"file(WRITE \"\${out}\" \"\${content}\")\n"
)
install(CODE "${SDK_HASH_SCRIPT}")
endif()
# Packaging
if(BUILD_NATIVE_COMPONENTS)
include(cmake/cpack/packaging.cmake)
endif()
# Superbuild
if(BUILD_NATIVE_COMPONENTS)
include(ExternalProject)
# Arguments
set(ARM_OPTIONS "${MCPI_OPTIONS}")
list(APPEND ARM_OPTIONS "-DMCPI_BUILD_MODE:STRING=arm")
list(APPEND ARM_OPTIONS "-DCMAKE_INSTALL_MESSAGE:STRING=NEVER")
list(APPEND ARM_OPTIONS "-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>")
if(NOT MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
if(DEFINED CMAKE_TOOLCHAIN_FILE)
set(ARM_TOOLCHAIN "${CMAKE_TOOLCHAIN_FILE}")
endif()
else()
set(ARM_TOOLCHAIN "${MCPI_CMAKE_TOOLCHAIN_FILE}")
endif()
if(DEFINED ARM_TOOLCHAIN)
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${ARM_TOOLCHAIN}")
endif()
# Build
ExternalProject_Add(arm-components
# Source Directory
DOWNLOAD_COMMAND ""
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
# Configure
CMAKE_CACHE_ARGS ${ARM_OPTIONS}
CMAKE_GENERATOR "Ninja Multi-Config"
# Build
BUILD_COMMAND
"${CMAKE_COMMAND}" "--build" "<BINARY_DIR>" "--config" "$<CONFIG>"
# Install
INSTALL_COMMAND
"${CMAKE_COMMAND}" "-E"
"rm" "-rf" "<INSTALL_DIR>/${MCPI_INSTALL_DIR}"
COMMAND
"${CMAKE_COMMAND}" "-E" "env" "DESTDIR="
"${CMAKE_COMMAND}" "--install" "<BINARY_DIR>" "--config" "$<CONFIG>"
# Use Terminal
USES_TERMINAL_CONFIGURE TRUE
USES_TERMINAL_BUILD TRUE
USES_TERMINAL_INSTALL TRUE
# Always Build
BUILD_ALWAYS TRUE
)
# Install
ExternalProject_Get_Property(arm-components INSTALL_DIR)
install(DIRECTORY "${INSTALL_DIR}/${MCPI_INSTALL_DIR}/" DESTINATION "${MCPI_INSTALL_DIR}")
endif()

19
Dockerfile Normal file
View File

@ -0,0 +1,19 @@
FROM debian:bullseye-slim
# Install
RUN \
apt-get update && \
apt-get install -y tini qemu-user && \
apt-get --fix-broken install -y && \
rm -rf /var/lib/apt/lists/*
# Copy
ADD ./out/server-amd64 /app
# Setup Working Directory
RUN mkdir /data
WORKDIR /data
# Setup Entrypoint
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["/app/usr/bin/minecraft-pi-reborn-legacy-server"]

37
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,37 @@
pipeline {
agent none
stages {
stage('Debian Buster') {
agent {
dockerfile {
filename 'scripts/ci/Dockerfile'
args '-v /var/run/docker.sock:/var/run/docker.sock --network host'
}
}
stages {
stage('Build') {
steps {
sh './scripts/ci/run.sh'
}
post {
success {
archiveArtifacts artifacts: 'out/*.AppImage*', fingerprint: true
}
}
}
stage('Publish') {
steps {
sh 'apt-get update && apt-get install -y docker.io'
sh 'rm -rf ./out/server-amd64'
sh './scripts/build.sh server amd64'
sh 'docker build --no-cache --tag thebrokenrail/minecraft-pi-reborn-legacy-server .'
withCredentials([usernamePassword(credentialsId: 'docker_hub_login', usernameVariable: 'DOCKER_HUB_USERNAME', passwordVariable: 'DOCKER_HUB_PASSWORD')]) {
sh 'docker login -u "${DOCKER_HUB_USERNAME}" -p "${DOCKER_HUB_PASSWORD}"'
}
sh 'docker push thebrokenrail/minecraft-pi-reborn-legacy-server'
}
}
}
}
}
}

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 TheBrokenRail
Copyright (c) 2022 TheBrokenRail
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -2,16 +2,8 @@
<img alt="Start Screen" src="images/start.png">
</p>
<p align="center">
<a href="https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases/latest"><img height="80" alt="Download as an AppImage" src="https://docs.appimage.org/_images/download-appimage-banner.svg" /></a>
<a href="https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn"><img height="80" alt="Download on Flathub" src="https://flathub.org/assets/badges/flathub-badge-en.svg" /></a>
<a href="https://github.com/Botspot/pi-apps"><img height="80" alt="Get it from Pi-Apps" src="https://github.com/Botspot/pi-apps/blob/master/icons/badge.png?raw=true" /></a>
</p>
# Minecraft: Pi Edition: Reborn [![Gitea Actions](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/actions/workflows/build.yml/badge.svg)](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/actions)
# Minecraft: Pi Edition: Reborn Legacy
Minecraft: Pi Edition Modding Project
Get started [here](docs/GETTING_STARTED.md)!
## Documentation
[View Documentation](docs/README.md)

View File

@ -1 +1 @@
3.0.0
2.4.6

@ -1 +0,0 @@
Subproject commit 5baa6b1948aeebb5e13af31ff62dc97f00a3b71e

View File

@ -1,60 +0,0 @@
# Download AppImage Runtime
set(RUNTIME_ARCH "unknown")
if(CPACK_MCPI_ARCH STREQUAL "armhf")
set(RUNTIME_ARCH "armhf")
elseif(CPACK_MCPI_ARCH STREQUAL "arm64")
set(RUNTIME_ARCH "aarch64")
elseif(CPACK_MCPI_ARCH STREQUAL "amd64")
set(RUNTIME_ARCH "x86_64")
endif()
set(RUNTIME "${CPACK_TOPLEVEL_DIRECTORY}/runtime")
file(DOWNLOAD
"https://github.com/AppImage/type2-runtime/releases/download/continuous/runtime-${RUNTIME_ARCH}"
"${RUNTIME}"
STATUS DOWNLOAD_STATUS
)
list(GET DOWNLOAD_STATUS 0 STATUS_CODE)
list(GET DOWNLOAD_STATUS 1 ERROR_MESSAGE)
if(NOT STATUS_CODE EQUAL 0)
message(FATAL_ERROR "Unable To Download AppImage Runtime: ${ERROR_MESSAGE}")
else()
message(STATUS "Downloaded AppImage Runtime: ${RUNTIME}")
endif()
# Package
set(APPIMAGE_ARCH "unknown")
if(CPACK_MCPI_ARCH STREQUAL "armhf")
set(APPIMAGE_ARCH "arm")
elseif(CPACK_MCPI_ARCH STREQUAL "arm64")
set(APPIMAGE_ARCH "arm_aarch64")
elseif(CPACK_MCPI_ARCH STREQUAL "amd64")
set(APPIMAGE_ARCH "x86_64")
endif()
execute_process(
COMMAND
"${CMAKE_COMMAND}" "-E" "env"
"ARCH=${APPIMAGE_ARCH}"
"VERSION=${CPACK_MCPI_VERSION}"
"appimagetool"
"--updateinformation" "zsync|${CPACK_MCPI_REPO}/releases/download/latest/${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}"
"--runtime-file" "${RUNTIME}"
"--comp" "zstd"
"${CPACK_TEMPORARY_DIRECTORY}"
"${CPACK_PACKAGE_FILE_NAME}${CPACK_MCPI_APPIMAGE_EXT}"
WORKING_DIRECTORY "${CPACK_PACKAGE_DIRECTORY}"
COMMAND_ERROR_IS_FATAL ANY
)
# Rename ZSync File
file(RENAME "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}" "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}")
# Summary Message
function(check_file name)
if(EXISTS "${CPACK_PACKAGE_DIRECTORY}/${name}")
message(STATUS "Generated: ${name}")
else()
message(FATAL_ERROR "Missing File: ${name}")
endif()
endfunction()
check_file("${CPACK_PACKAGE_FILE_NAME}${CPACK_MCPI_APPIMAGE_EXT}")
check_file("${CPACK_PACKAGE_FILE_NAME_ZSYNC}${CPACK_MCPI_APPIMAGE_ZSYNC_EXT}")

View File

@ -1,32 +0,0 @@
# CPack
set(CPACK_PACKAGE_NAME "${MCPI_APP_NAME}")
set(CPACK_PACKAGE_VENDOR "${MCPI_AUTHOR} & Mojang AB")
set(CPACK_VERBATIM_VARIABLES TRUE)
set(CPACK_MONOLITHIC_INSTALL TRUE)
get_package_file_name(CPACK_PACKAGE_FILE_NAME "${MCPI_VERSION}")
get_package_file_name(CPACK_PACKAGE_FILE_NAME_ZSYNC "latest")
# Version
string(REPLACE "." ";" VERSION_LIST "${MCPI_VERSION}")
list(GET VERSION_LIST 0 CPACK_PACKAGE_VERSION_MAJOR)
list(GET VERSION_LIST 1 CPACK_PACKAGE_VERSION_MINOR)
list(GET VERSION_LIST 2 CPACK_PACKAGE_VERSION_PATCH)
# AppImage
if(MCPI_IS_APPIMAGE_BUILD)
set(CPACK_GENERATOR "External")
set(CPACK_EXTERNAL_ENABLE_STAGING TRUE)
set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/appimage.cmake")
# Pass Variable To CPack
macro(pass_to_cpack var)
set("CPACK_MCPI_${var}" "${MCPI_${var}}")
endmacro()
pass_to_cpack(VERSION)
pass_to_cpack(ARCH)
pass_to_cpack(REPO)
pass_to_cpack(APPIMAGE_EXT)
pass_to_cpack(APPIMAGE_ZSYNC_EXT)
endif()
# Package
include(CPack)

View File

@ -0,0 +1,12 @@
# Read Hex Data
file(READ "${EMBED_IN}" data HEX)
# Convert Hex Data For C Compatibility
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," data "${data}")
# Get C Name
get_filename_component(name "${EMBED_IN}" NAME)
string(MAKE_C_IDENTIFIER "${name}" name)
# Write Data
file(WRITE "${EMBED_OUT}" "#include <stddef.h>\nconst unsigned char ${name}[] = {${data}};\nconst size_t ${name}_len = sizeof (${name});\n")

View File

@ -1,27 +0,0 @@
# Build Mode
set(MCPI_BUILD_MODE "native" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code")
set_property(CACHE MCPI_BUILD_MODE PROPERTY STRINGS "arm" "native")
if(MCPI_BUILD_MODE STREQUAL "arm")
set(BUILD_ARM_COMPONENTS TRUE)
set(BUILD_NATIVE_COMPONENTS FALSE)
elseif(MCPI_BUILD_MODE STREQUAL "native")
set(BUILD_ARM_COMPONENTS FALSE)
set(BUILD_NATIVE_COMPONENTS TRUE)
else()
message(FATAL_ERROR "Invalid Mode")
endif()
# Specify Options
set(MCPI_OPTIONS "")
function(mcpi_option name description type default)
set(full_name "MCPI_${name}")
set("${full_name}" "${default}" CACHE "${type}" "${description}")
list(APPEND MCPI_OPTIONS "-D${full_name}:${type}=${${full_name}}")
set(MCPI_OPTIONS "${MCPI_OPTIONS}" PARENT_SCOPE)
endfunction()
# Clear External CFLAGS When Building ARM Components
if(BUILD_ARM_COMPONENTS)
unset(ENV{CFLAGS})
unset(ENV{CXXFLAGS})
endif()

View File

@ -1,89 +0,0 @@
# Specify Options
mcpi_option(OPEN_SOURCE_ONLY "Only Install Open-Source Code (Will Result In Broken Install)" BOOL FALSE)
mcpi_option(IS_APPIMAGE_BUILD "AppImage Build" BOOL FALSE)
mcpi_option(IS_FLATPAK_BUILD "Flatpak Build" BOOL FALSE)
if(MCPI_IS_APPIMAGE_BUILD AND MCPI_IS_FLATPAK_BUILD)
message(FATAL_ERROR "Invalid Build Configuration")
endif()
# Prebuilt ARMHF Toolchain
if(BUILD_NATIVE_COMPONENTS)
set(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN FALSE)
if(NOT IS_ARM_TARGETING)
set(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN TRUE)
endif()
if(MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
include("${CMAKE_CURRENT_LIST_DIR}/prebuilt-armhf-toolchain.cmake")
endif()
endif()
# Media Layer
set(DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE FALSE)
if(BUILD_NATIVE_COMPONENTS AND NOT IS_ARM_TARGETING)
set(DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE TRUE)
endif()
mcpi_option(USE_MEDIA_LAYER_TRAMPOLINE "Whether To Enable The Media Layer Trampoline" BOOL "${DEFAULT_USE_MEDIA_LAYER_TRAMPOLINE}")
if(MCPI_USE_MEDIA_LAYER_TRAMPOLINE)
set(BUILD_MEDIA_LAYER_CORE "${BUILD_NATIVE_COMPONENTS}")
else()
set(BUILD_MEDIA_LAYER_CORE "${BUILD_ARM_COMPONENTS}")
endif()
# App Information
mcpi_option(APP_NAME "App Name" STRING "minecraft-pi-reborn")
mcpi_option(APP_ID "App ID" STRING "com.thebrokenrail.MCPIReborn")
mcpi_option(APP_TITLE "App Title" STRING "Minecraft: Pi Edition: Reborn")
# Skin Server
mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data")
# Discord Invite URL
mcpi_option(DISCORD_INVITE "Discord Invite URL" STRING "https://discord.gg/mcpi-revival-740287937727561779")
# Version
set_property(
DIRECTORY
APPEND
PROPERTY CMAKE_CONFIGURE_DEPENDS VERSION
)
file(STRINGS "${CMAKE_CURRENT_LIST_DIR}/../../VERSION" MCPI_VERSION)
file(TIMESTAMP "${CMAKE_CURRENT_LIST_DIR}/../../VERSION" MCPI_VERSION_DATE "%Y-%m-%d" UTC)
# Author
mcpi_option(AUTHOR "Author" STRING "TheBrokenRail")
# Homepage
mcpi_option(REPO_HOST "Repository Host" STRING "https://gitea.thebrokenrail.com")
mcpi_option(REPO_PATH "Repository Path" STRING "minecraft-pi-reborn/minecraft-pi-reborn")
mcpi_option(REPO "Repository URL" STRING "${MCPI_REPO_HOST}/${MCPI_REPO_PATH}")
# Documentation URL
mcpi_option(DOCS "Documentation URL" STRING "${MCPI_REPO}/src/tag/${MCPI_VERSION}/docs/")
# Packaging
set(MCPI_ARCH "unknown")
include(CheckSymbolExists)
function(check_arch symbol name)
set(CMAKE_REQUIRED_QUIET TRUE)
check_symbol_exists("${symbol}" "" "IS_ARCH_${name}")
unset(CMAKE_REQUIRED_QUIET)
if("${IS_ARCH_${name}}")
set(MCPI_ARCH "${name}" PARENT_SCOPE)
endif()
endfunction()
check_arch("__arm__" "armhf")
check_arch("__aarch64__" "arm64")
check_arch("__x86_64__" "amd64")
macro(get_package_file_name out version)
set("${out}" "${MCPI_APP_NAME}-${version}-${MCPI_ARCH}")
endmacro()
# AppImage
if(MCPI_IS_APPIMAGE_BUILD)
mcpi_option(APPIMAGE_EXT "AppImage Extension" STRING ".AppImage")
mcpi_option(APPIMAGE_ZSYNC_EXT "AppImage Update Extension" STRING "${MCPI_APPIMAGE_EXT}.zsync")
mcpi_option(APPIMAGE_JSON_URL "AppImage Update Checker URL" STRING "${MCPI_REPO_HOST}/api/v1/repos/${MCPI_REPO_PATH}/releases/latest")
mcpi_option(APPIMAGE_VERSION_PLACEHOLDER "Version Placeholder In AppImage Download URL" STRING "%VERSION%")
get_package_file_name(appimage_package_file_name "${MCPI_APPIMAGE_VERSION_PLACEHOLDER}")
mcpi_option(APPIMAGE_DOWNLOAD_URL "AppImage Download URL" STRING "${MCPI_REPO}/releases/download/${MCPI_APPIMAGE_VERSION_PLACEHOLDER}/${appimage_package_file_name}${MCPI_APPIMAGE_EXT}")
endif()

View File

@ -1,33 +0,0 @@
# Specify Installation Paths
set(MCPI_INSTALL_DIR "lib/${MCPI_APP_NAME}")
set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin")
set(MCPI_LEGAL_DIR "${MCPI_INSTALL_DIR}/legal") # For Software Licenses
set(MCPI_SDK_DIR "${MCPI_INSTALL_DIR}/sdk")
set(MCPI_SDK_LIB_DIR "${MCPI_SDK_DIR}/lib")
set(MCPI_SDK_INCLUDE_DIR "${MCPI_SDK_DIR}/include")
# Library Directory
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
if(BUILD_ARM_COMPONENTS)
string(APPEND MCPI_LIB_DIR "/arm")
elseif(BUILD_NATIVE_COMPONENTS)
string(APPEND MCPI_LIB_DIR "/native")
endif()
# Share Directory
set(MCPI_SHARE_DIR "share")
if(MCPI_IS_APPIMAGE_BUILD)
string(PREPEND MCPI_SHARE_DIR "usr/")
endif()
# Specify Default Installation Prefix
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(DEFAULT_PREFIX "/usr")
if(MCPI_IS_APPIMAGE_BUILD)
set(DEFAULT_PREFIX "/")
elseif(MCPI_IS_FLATPAK_BUILD)
set(DEFAULT_PREFIX "/app")
endif()
set(CMAKE_INSTALL_PREFIX "${DEFAULT_PREFIX}" CACHE PATH "Install Prefix" FORCE)
set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT FALSE)
endif()

View File

@ -1,88 +0,0 @@
# Target
set(target "arm-none-linux-gnueabihf")
# Pick Archive
set(toolchain_version "13.3.rel1")
execute_process(COMMAND uname -m OUTPUT_VARIABLE arch OUTPUT_STRIP_TRAILING_WHITESPACE)
if(arch STREQUAL "x86_64")
set(toolchain_file "arm-gnu-toolchain-${toolchain_version}-x86_64-${target}.tar.xz")
elseif(arch STREQUAL "aarch64" OR arch STREQUAL "armv8b" OR arch STREQUAL "armv8l")
set(toolchain_file "arm-gnu-toolchain-${toolchain_version}-aarch64-${target}.tar.xz")
else()
message(FATAL_ERROR "Unable To Download Prebuilt ARMHF Toolchain")
endif()
# Download If Needed
include(FetchContent)
FetchContent_Declare(prebuilt-armhf-toolchain
URL "${CMAKE_CURRENT_LIST_DIR}/../../archives/${toolchain_file}"
)
FetchContent_MakeAvailable(prebuilt-armhf-toolchain)
set(toolchain_dir "${prebuilt-armhf-toolchain_SOURCE_DIR}")
# Force Toolchain
file(WRITE "${toolchain_dir}/toolchain.cmake"
"set(CMAKE_C_COMPILER \"\${CMAKE_CURRENT_LIST_DIR}/bin/${target}-gcc\")\n"
"set(CMAKE_CXX_COMPILER \"\${CMAKE_CURRENT_LIST_DIR}/bin/${target}-g++\")\n"
"set(CMAKE_SYSTEM_NAME \"Linux\")\n"
"set(CMAKE_SYSTEM_PROCESSOR \"arm\")\n"
"set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\n"
)
force_set(MCPI_CMAKE_TOOLCHAIN_FILE "${toolchain_dir}/toolchain.cmake" FILEPATH)
# Build Sysroot
set(sysroot_dir "${CMAKE_CURRENT_BINARY_DIR}/bundled-armhf-sysroot")
set(sysroot_dir_debug "${sysroot_dir}/debug")
set(sysroot_dir_release "${sysroot_dir}/release")
if("${toolchain_dir}/bin/${target}-gcc" IS_NEWER_THAN "${sysroot_dir}")
# Create Directory
file(REMOVE_RECURSE "${sysroot_dir}")
file(MAKE_DIRECTORY "${sysroot_dir_debug}")
file(MAKE_DIRECTORY "${sysroot_dir_release}")
# Copy Files From Toolchain
file(
COPY "${toolchain_dir}/${target}/libc/"
DESTINATION "${sysroot_dir_debug}"
USE_SOURCE_PERMISSIONS
FILES_MATCHING
PATTERN "*.so*"
)
# Delete Unneeded Files
file(REMOVE_RECURSE "${sysroot_dir_debug}/usr/lib/audit")
file(REMOVE_RECURSE "${sysroot_dir_debug}/usr/lib/gconv")
# Strip Files
file(COPY "${sysroot_dir_debug}/." DESTINATION "${sysroot_dir_release}")
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE "${sysroot_dir_release}/*")
foreach(file IN LISTS files)
execute_process(
COMMAND "${toolchain_dir}/bin/${target}-strip" "${file}"
RESULT_VARIABLE ret
ERROR_QUIET
)
# Delete Invalid Files
if(NOT ret EQUAL 0)
file(REMOVE "${file}")
endif()
endforeach()
endif()
# Install Sysroot (Skipping Empty Directories)
function(install_arm_sysroot_config config)
set(dir "${sysroot_dir_${config}}")
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE RELATIVE "${dir}" "${dir}/*")
foreach(file IN LISTS files)
cmake_path(GET file PARENT_PATH parent)
install(
PROGRAMS "${dir}/${file}"
DESTINATION "${MCPI_INSTALL_DIR}/sysroot/${parent}"
CONFIGURATIONS "${config}"
)
endforeach()
endfunction()
function(install_arm_sysroot)
install_arm_sysroot_config(debug)
install_arm_sysroot_config(release)
endfunction()

View File

@ -0,0 +1,78 @@
# Pick URL
execute_process(COMMAND uname -m OUTPUT_VARIABLE arch OUTPUT_STRIP_TRAILING_WHITESPACE)
if(arch STREQUAL "x86_64")
set(toolchain_url "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf.tar.xz")
set(toolchain_sha256 "aa074fa8371a4f73fecbd16bd62c8b1945f23289e26414794f130d6ccdf8e39c")
elseif(arch STREQUAL "aarch64" OR arch STREQUAL "armv8b" OR arch STREQUAL "armv8l")
set(toolchain_url "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-aarch64-arm-none-linux-gnueabihf.tar.xz")
set(toolchain_sha256 "fccd7af76988da2b077f939eb2a78baa9935810918d2bf3f837bc74f52efa825")
else()
message(FATAL_ERROR "Unable To Download Prebuilt ARMHF Toolchain")
endif()
# Download If Needed
include(FetchContent)
set(FETCHCONTENT_QUIET FALSE)
FetchContent_Declare(
prebuilt-armhf-toolchain
URL "${toolchain_url}"
URL_HASH "SHA256=${toolchain_sha256}"
)
FetchContent_MakeAvailable(prebuilt-armhf-toolchain)
set(FETCHCONTENT_QUIET TRUE)
set(toolchain_dir "${prebuilt-armhf-toolchain_SOURCE_DIR}")
# Force Toolchain
file(WRITE "${toolchain_dir}/toolchain.cmake"
"set(CMAKE_C_COMPILER \"\${CMAKE_CURRENT_LIST_DIR}/bin/arm-none-linux-gnueabihf-gcc\")\n"
"set(CMAKE_CXX_COMPILER \"\${CMAKE_CURRENT_LIST_DIR}/bin/arm-none-linux-gnueabihf-g++\")\n"
"set(CMAKE_SYSTEM_NAME \"Linux\")\n"
"set(CMAKE_SYSTEM_PROCESSOR \"arm\")\n"
"set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)\n"
)
set(CMAKE_TOOLCHAIN_FILE "${toolchain_dir}/toolchain.cmake" CACHE STRING "" FORCE)
# Build Sysroot
set(sysroot_dir "${CMAKE_CURRENT_BINARY_DIR}/bundled-armhf-sysroot")
if("${toolchain_dir}/bin/arm-none-linux-gnueabihf-gcc" IS_NEWER_THAN "${sysroot_dir}")
# Create Directory
file(REMOVE_RECURSE "${sysroot_dir}")
file(MAKE_DIRECTORY "${sysroot_dir}")
# Copy Files From Toolchain
file(
COPY "${toolchain_dir}/arm-none-linux-gnueabihf/libc/"
DESTINATION "${sysroot_dir}"
USE_SOURCE_PERMISSIONS
FILES_MATCHING
PATTERN "*.so*"
)
# Delete Unneeded Files
file(REMOVE_RECURSE "${sysroot_dir}/usr/lib/audit")
# Strip Files
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE "${sysroot_dir}/*")
foreach(file IN LISTS files)
execute_process(COMMAND "${toolchain_dir}/bin/arm-none-linux-gnueabihf-strip" "${file}" RESULT_VARIABLE ret)
# Check Result
if(NOT ret EQUAL 0)
# Delete Invalid Files
file(REMOVE "${file}")
endif()
endforeach()
# Setup gconv
file(
COPY "${toolchain_dir}/arm-none-linux-gnueabihf/libc/usr/lib/gconv/gconv-modules"
DESTINATION "${sysroot_dir}/usr/lib/gconv"
USE_SOURCE_PERMISSIONS
)
endif()
# Install Sysroot (Skipping Empty Directories)
file(GLOB_RECURSE files LIST_DIRECTORIES FALSE RELATIVE "${sysroot_dir}" "${sysroot_dir}/*")
foreach(file IN LISTS files)
get_filename_component(parent "${file}" DIRECTORY)
install(PROGRAMS "${sysroot_dir}/${file}" DESTINATION "${MCPI_INSTALL_DIR}/sysroot/${parent}")
endforeach()

View File

@ -9,7 +9,6 @@ macro(setup_toolchain target)
add_target_variant(unknown)
add_target_variant(none)
add_target_variant(pc)
# Find Compiler
macro(find_compiler output name)
set(possible_names "")
@ -27,11 +26,13 @@ macro(setup_toolchain target)
endmacro()
find_compiler(CMAKE_C_COMPILER "gcc")
find_compiler(CMAKE_CXX_COMPILER "g++")
# Extra
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Custom Search Paths
if(NOT DEFINED ENV{MCPI_TOOLCHAIN_USE_DEFAULT_SEARCH_PATHS})
# Find Root
set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}" "/usr")
# pkg-config
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/${target}/pkgconfig:/usr/${target}/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig")
endif()
endmacro()

26
cmake/util.cmake Normal file
View File

@ -0,0 +1,26 @@
# Symlink Function
function(install_symlink target link)
get_filename_component(parent "${link}" DIRECTORY)
if(parent STREQUAL "")
set(parent ".")
endif()
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/symlink/${parent}")
file(CREATE_LINK "${target}" "${CMAKE_BINARY_DIR}/symlink/${link}" SYMBOLIC)
install(FILES "${CMAKE_BINARY_DIR}/symlink/${link}" DESTINATION "${parent}")
endfunction()
# Embed Resources
set(util_list_dir "${CMAKE_CURRENT_LIST_DIR}")
function(embed_resource target file)
# Get C Name
get_filename_component(name "${file}" NAME)
string(MAKE_C_IDENTIFIER "${name}" name)
# Add Command
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${name}.c"
COMMAND "${CMAKE_COMMAND}"
ARGS "-DEMBED_IN=${CMAKE_CURRENT_SOURCE_DIR}/${file}" "-DEMBED_OUT=${CMAKE_CURRENT_BINARY_DIR}/${name}.c" "-P" "${util_list_dir}/embed-resource.cmake"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${file}" "${util_list_dir}/embed-resource.cmake"
)
# Add To Target
target_sources("${target}" PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
endfunction()

View File

@ -1,12 +0,0 @@
# Read Hex Data
file(READ "${EMBED_IN}" data HEX)
# Convert Hex Data For C Compatibility
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," data "${data}")
# Get C Name
cmake_path(GET EMBED_OUT STEM name)
# Write Data
file(WRITE "${EMBED_OUT}"
"#include <stddef.h>\n"
"const unsigned char ${name}[] = {${data}};\n"
"const size_t ${name}_len = sizeof (${name});\n"
)

View File

@ -1,91 +0,0 @@
# Symlink Function
function(install_symlink target link)
cmake_path(GET link PARENT_PATH parent)
if(parent STREQUAL "")
set(parent ".")
endif()
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/symlink/${parent}")
file(CREATE_LINK "${target}" "${CMAKE_BINARY_DIR}/symlink/${link}" SYMBOLIC)
install(FILES "${CMAKE_BINARY_DIR}/symlink/${link}" DESTINATION "${parent}")
endfunction()
# Embed Resources
set(util_list_dir "${CMAKE_CURRENT_LIST_DIR}")
function(embed_resource target file)
# Get C Name
cmake_path(GET file FILENAME name)
string(MAKE_C_IDENTIFIER "${name}" name)
# Add Command
set(in "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
set(out "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
set(script "${util_list_dir}/embed-resource.cmake")
add_custom_command(OUTPUT "${out}"
COMMAND "${CMAKE_COMMAND}"
ARGS "-DEMBED_IN=${in}" "-DEMBED_OUT=${out}" "-P" "${script}"
DEPENDS "${in}" "${script}"
VERBATIM
)
# Add To Target
target_sources("${target}" PRIVATE "${out}")
endfunction()
# Nicer Output
function(message log_level)
if((NOT MESSAGE_QUIET) OR (NOT (log_level STREQUAL "STATUS" OR log_level MATCHES "^CHECK_")))
_message("${log_level}" ${ARGN})
endif()
endfunction()
# Exporting Targets And Headers
macro(_get_sdk_header_dir target)
set(sdk_dir "${MCPI_SDK_INCLUDE_DIR}/${target}")
endmacro()
function(setup_header_dirs target)
_get_sdk_header_dir("${target}")
# Get Header Type
set(header_type "PUBLIC")
get_target_property(type "${target}" TYPE)
if ("${type}" STREQUAL "INTERFACE_LIBRARY")
set(header_type "INTERFACE")
endif()
# Loop
foreach(dir IN LISTS ARGN)
# Add To Target
target_include_directories("${target}" "${header_type}" "$<BUILD_INTERFACE:${dir}>")
# Add To SDK
if(BUILD_ARM_COMPONENTS)
install(
DIRECTORY "${dir}/"
DESTINATION "${sdk_dir}"
FILES_MATCHING
PATTERN "*.h"
)
endif()
endforeach()
# Add SDK Headers To Target
if(BUILD_ARM_COMPONENTS)
target_include_directories("${target}" "${header_type}" "$<INSTALL_INTERFACE:${sdk_dir}>")
endif()
endfunction()
function(setup_library target should_install should_export)
# Install
if(should_install)
install(TARGETS "${target}" DESTINATION "${MCPI_LIB_DIR}")
endif()
# SDK
if(should_export AND BUILD_ARM_COMPONENTS)
install(TARGETS "${target}" EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
endif()
endfunction()
# Force Set Configuration Variable
function(force_set name value type)
set("${name}" "${value}" CACHE "${type}" "" FORCE)
mark_as_advanced(FORCE "${name}")
endfunction()
# Make Directory
function(set_and_mkdir name dir)
set("${name}" "${dir}" PARENT_SCOPE)
file(MAKE_DIRECTORY "${dir}")
endfunction()

View File

@ -1,30 +1,22 @@
project(dependencies)
# stb_image
# LibPNG
if(BUILD_ARM_COMPONENTS)
add_subdirectory(stb_image)
add_subdirectory(libpng)
endif()
# Minecraft: Pi Edition
if(BUILD_ARM_COMPONENTS AND NOT MCPI_OPEN_SOURCE_ONLY)
add_subdirectory(minecraft-pi)
endif()
# Zenity (Minimal Build)
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_SERVER_MODE)
add_subdirectory(zenity)
endif()
# LIEF
if(BUILD_NATIVE_COMPONENTS OR BUILD_MEDIA_LAYER_CORE)
if(BUILD_NATIVE_COMPONENTS OR (BUILD_ARM_COMPONENTS AND NOT MCPI_SERVER_MODE AND NOT MCPI_USE_MEDIA_LAYER_PROXY))
add_subdirectory(LIEF)
endif()
# Extra Runtime
add_subdirectory(runtime)
# GLFW
if(BUILD_NATIVE_COMPONENTS OR BUILD_MEDIA_LAYER_CORE)
add_subdirectory(glfw)
endif()
# ImGui
if(BUILD_NATIVE_COMPONENTS)
add_subdirectory(imgui)
endif()
# UTF8-CPP
add_subdirectory(utf8cpp)
# Symbol Processor
if(BUILD_ARM_COMPONENTS)
add_subdirectory(symbol-processor)
# QEMU
if(BUILD_NATIVE_COMPONENTS AND NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64"))
add_subdirectory(qemu)
endif()

View File

@ -6,38 +6,34 @@ add_compile_options(-w -Wno-psabi)
## LIEF
# Options
force_set(LIEF_C_API FALSE BOOL)
force_set(LIEF_EXAMPLES FALSE BOOL)
force_set(LIEF_PYTHON_API FALSE BOOL)
force_set(LIEF_TESTS FALSE BOOL)
force_set(LIEF_USE_CCACHE FALSE BOOL)
force_set(LIEF_LOGGING FALSE BOOL)
force_set(LIEF_LOGGING_DEBUG FALSE BOOL)
force_set(LIEF_ENABLE_JSON FALSE BOOL)
force_set(LIEF_ELF TRUE BOOL)
force_set(LIEF_PE FALSE BOOL)
force_set(LIEF_MACHO FALSE BOOL)
force_set(LIEF_DEX FALSE BOOL)
force_set(LIEF_ART FALSE BOOL)
force_set(LIEF_OAT FALSE BOOL)
force_set(LIEF_VDEX FALSE BOOL)
set(BUILD_SHARED_LIBS TRUE CACHE BOOL "" FORCE)
set(LIEF_C_API FALSE CACHE BOOL "" FORCE)
set(LIEF_EXAMPLES FALSE CACHE BOOL "" FORCE)
set(LIEF_PYTHON_API FALSE CACHE BOOL "" FORCE)
set(LIEF_TESTS FALSE CACHE BOOL "" FORCE)
set(LIEF_USE_CCACHE FALSE CACHE BOOL "" FORCE)
set(LIEF_LOGGING FALSE CACHE BOOL "" FORCE)
set(LIEF_LOGGING_DEBUG FALSE CACHE BOOL "" FORCE)
set(LIEF_ENABLE_JSON FALSE CACHE BOOL "" FORCE)
set(LIEF_ELF TRUE CACHE BOOL "" FORCE)
set(LIEF_PE FALSE CACHE BOOL "" FORCE)
set(LIEF_MACHO FALSE CACHE BOOL "" FORCE)
set(LIEF_DEX FALSE CACHE BOOL "" FORCE)
set(LIEF_ART FALSE CACHE BOOL "" FORCE)
set(LIEF_OAT FALSE CACHE BOOL "" FORCE)
set(LIEF_VDEX FALSE CACHE BOOL "" FORCE)
# Download
set(MESSAGE_QUIET TRUE)
add_subdirectory(src EXCLUDE_FROM_ALL SYSTEM)
unset(MESSAGE_QUIET)
add_subdirectory(src EXCLUDE_FROM_ALL)
# Ensure Build
add_custom_target(LIEF-build ALL DEPENDS LIB_LIEF)
# Install
setup_library(LIB_LIEF TRUE TRUE)
install(TARGETS LIB_LIEF DESTINATION "${MCPI_LIB_DIR}")
if(BUILD_ARM_COMPONENTS)
install(TARGETS LIB_LIEF EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
endif()
# License
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/LIEF")
# Fix Flags
function(fix_flags property)
get_target_property(flags LIB_LIEF "${property}")
list(REMOVE_ITEM flags "_GLIBCXX_USE_CXX11_ABI=1")
set_target_properties(LIB_LIEF PROPERTIES "${property}" "${flags}")
endfunction()
fix_flags(COMPILE_DEFINITIONS)
fix_flags(INTERFACE_COMPILE_DEFINITIONS)

@ -1 +1 @@
Subproject commit d4900dab6a9eea864fb14ed1ff7ea5b9f8678e04
Subproject commit 2169578d46934c973fdbfa2fae23b192e3cac8a0

View File

@ -1,26 +0,0 @@
project(glfw)
# Silence Warnings
add_compile_options(-w)
## GLFW
# Download
force_set(GLFW_BUILD_EXAMPLES FALSE BOOL)
force_set(GLFW_BUILD_TESTS FALSE BOOL)
force_set(GLFW_BUILD_DOCS FALSE BOOL)
force_set(GLFW_INSTALL FALSE BOOL)
force_set(GLFW_BUILD_WIN32 FALSE BOOL)
force_set(GLFW_BUILD_COCOA FALSE BOOL)
force_set(GLFW_BUILD_X11 TRUE BOOL)
force_set(GLFW_BUILD_WAYLAND TRUE BOOL)
force_set(GLFW_LIBRARY_TYPE "SHARED" STRING)
set(MESSAGE_QUIET TRUE)
add_subdirectory(src EXCLUDE_FROM_ALL SYSTEM)
unset(MESSAGE_QUIET)
# Install
setup_library(glfw TRUE TRUE)
# License
install(FILES src/LICENSE.md DESTINATION "${MCPI_LEGAL_DIR}/GLFW")

@ -1 +0,0 @@
Subproject commit 21fea01161e0d6b70c0c5c1f52dc8e7a7df14a50

View File

@ -1,52 +0,0 @@
project(imgui)
# Silence Warnings
add_compile_options(-w)
## ImGui
# Build
add_library(imgui SHARED
src/imgui.cpp
src/imgui_draw.cpp
src/imgui_tables.cpp
src/imgui_widgets.cpp
src/misc/cpp/imgui_stdlib.cpp
src/backends/imgui_impl_glfw.cpp
src/backends/imgui_impl_opengl2.cpp
)
setup_header_dirs(imgui
"${CMAKE_CURRENT_SOURCE_DIR}/src"
"${CMAKE_CURRENT_SOURCE_DIR}/src/backends"
"${CMAKE_CURRENT_SOURCE_DIR}/src/misc/cpp"
)
# OpenGL
add_subdirectory(glad)
target_link_libraries(imgui PUBLIC glfw glad)
# Fonts
embed_resource(imgui src/misc/fonts/Roboto-Medium.ttf)
embed_resource(imgui src/misc/fonts/Cousine-Regular.ttf)
# Configure
target_compile_definitions(imgui PUBLIC
IMGUI_DISABLE_DEMO_WINDOWS
IMGUI_DISABLE_DEBUG_TOOLS
IMGUI_DISABLE_DEFAULT_FONT
IMGUI_DISABLE_OBSOLETE_FUNCTIONS
)
# Patch
execute_process(
COMMAND "patch" "-p1" "--forward" "--reject-file=-"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src"
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/fix-hidpi.patch"
OUTPUT_QUIET
)
# Install
setup_library(imgui TRUE FALSE)
# License
install(FILES src/LICENSE.txt src/docs/FONTS.md DESTINATION "${MCPI_LEGAL_DIR}/ImGui")

View File

@ -1,55 +0,0 @@
--- a/backends/imgui_impl_glfw.cpp
+++ b/backends/imgui_impl_glfw.cpp
@@ -422,6 +422,21 @@ void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
io.AddFocusEvent(focused != 0);
}
+static void ImGui_ImplGlfw_ScaleMousePos(GLFWwindow* window, double &x, double &y) {
+ // Get Window Size
+ int window_width, window_height;
+ glfwGetWindowSize(window, &window_width, &window_height);
+ if (window_width <= 0 || window_height <= 0) {
+ return;
+ }
+ // Get Framebuffer Size
+ int framebuffer_width, framebuffer_height;
+ glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
+ // Multiply
+ x *= double(framebuffer_width) / double(window_width);
+ y *= double(framebuffer_height) / double(window_height);
+}
+
void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
{
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
@@ -429,6 +444,7 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
bd->PrevUserCallbackCursorPos(window, x, y);
ImGuiIO& io = ImGui::GetIO();
+ ImGui_ImplGlfw_ScaleMousePos(window, x, y);
io.AddMousePosEvent((float)x, (float)y);
bd->LastValidMousePos = ImVec2((float)x, (float)y);
}
@@ -738,6 +754,7 @@ static void ImGui_ImplGlfw_UpdateMouseData()
{
double mouse_x, mouse_y;
glfwGetCursorPos(window, &mouse_x, &mouse_y);
+ ImGui_ImplGlfw_ScaleMousePos(window, mouse_x, mouse_y);
bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
}
@@ -831,13 +848,9 @@ void ImGui_ImplGlfw_NewFrame()
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?");
// Setup display size (every frame to accommodate for window resizing)
- int w, h;
int display_w, display_h;
- glfwGetWindowSize(bd->Window, &w, &h);
glfwGetFramebufferSize(bd->Window, &display_w, &display_h);
- io.DisplaySize = ImVec2((float)w, (float)h);
- if (w > 0 && h > 0)
- io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);
+ io.DisplaySize = ImVec2((float)display_w, (float)display_h);
// Setup time step
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)

View File

@ -1,49 +0,0 @@
project(imgui-glad)
# Directories
set_and_mkdir(GLAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/glad")
set_and_mkdir(GLAD_SRC_DIR "${GLAD_DIR}/src")
set_and_mkdir(GLAD_INCLUDE_DIR "${GLAD_DIR}/include")
# Files
set(GLAD_SOURCES
"${GLAD_INCLUDE_DIR}/KHR/khrplatform.h"
"${GLAD_INCLUDE_DIR}/glad/glad.h"
"${GLAD_SRC_DIR}/glad.c"
)
# Find Python
find_package(Python REQUIRED QUIET)
# Generate
add_custom_command(
OUTPUT ${GLAD_SOURCES}
COMMAND "${Python_EXECUTABLE}"
ARGS "-m" "glad"
"--out" "${GLAD_DIR}"
"--api" "gl=1.1"
"--generator" "c"
"--reproducible"
"--quiet"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src"
VERBATIM
)
# Build
add_library(glad SHARED ${GLAD_SOURCES})
target_compile_definitions(glad
PUBLIC GLAD_GLAPI_EXPORT
PRIVATE GLAD_GLAPI_EXPORT_BUILD
)
# Link
target_link_libraries(glad PRIVATE dl)
# Headers
setup_header_dirs(glad
"${GLAD_INCLUDE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/include"
)
# Install
setup_library(glad TRUE FALSE)

View File

@ -1,2 +0,0 @@
#pragma once
#include <glad/glad.h>

@ -1 +0,0 @@
Subproject commit e86f90457371c6233053bacf0d6f486a51ddcd67

@ -1 +0,0 @@
Subproject commit 6982ce43f5b143c5dce5fab0ce07dd4867b705ae

33
dependencies/libpng/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,33 @@
project(libpng)
# ZLib (Needed By libpng)
add_subdirectory(zlib)
# Silence Warnings
add_compile_options(-w)
## LibPNG
# Options
set(PNG_TESTS FALSE CACHE BOOL "" FORCE)
set(PNG_NO_STDIO FALSE CACHE BOOL "" FORCE)
set(PNG_BUILD_ZLIB TRUE CACHE BOOL "" FORCE)
# Download
set(ZLIB_LIBRARY zlibstatic)
set(ZLIB_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/zlib/src" "${CMAKE_CURRENT_BINARY_DIR}/zlib/src")
add_subdirectory(src EXCLUDE_FROM_ALL)
# Use Symbol Versioning
set_target_properties(png12 PROPERTIES LINK_OPTIONS "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libpng.vers")
# Ensure Build
add_custom_target(png12-build ALL DEPENDS png12)
# Install
install(TARGETS png12 DESTINATION "${MCPI_LIB_DIR}")
if(BUILD_ARM_COMPONENTS)
install(TARGETS png12 zlibstatic EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
endif()
# License
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/libpng")

208
dependencies/libpng/libpng.vers vendored Normal file
View File

@ -0,0 +1,208 @@
PNG12_0 {global:
png_libpng_ver;
png_pass_start;
png_pass_inc;
png_pass_ystart;
png_pass_yinc;
png_pass_mask;
png_pass_dsp_mask;
png_access_version_number;
png_set_sig_bytes;
png_sig_cmp;
png_check_sig;
png_create_read_struct;
png_create_write_struct;
png_get_compression_buffer_size;
png_set_compression_buffer_size;
png_reset_zstream;
png_create_read_struct_2;
png_create_write_struct_2;
png_write_chunk;
png_write_chunk_start;
png_write_chunk_data;
png_write_chunk_end;
png_create_info_struct;
png_info_init;
png_info_init_3;
png_write_info_before_PLTE;
png_write_info;
png_read_info;
png_convert_to_rfc1123;
png_convert_from_struct_tm;
png_convert_from_time_t;
png_set_expand;
png_set_expand_gray_1_2_4_to_8;
png_set_palette_to_rgb;
png_set_tRNS_to_alpha;
png_set_gray_1_2_4_to_8;
png_set_bgr;
png_set_gray_to_rgb;
png_set_rgb_to_gray;
png_set_rgb_to_gray_fixed;
png_get_rgb_to_gray_status;
png_build_grayscale_palette;
png_set_strip_alpha;
png_set_swap_alpha;
png_set_invert_alpha;
png_set_filler;
png_set_add_alpha;
png_set_swap;
png_set_packing;
png_set_packswap;
png_set_shift;
png_set_interlace_handling;
png_set_invert_mono;
png_set_background;
png_set_strip_16;
png_set_dither;
png_set_gamma;
png_permit_empty_plte;
png_set_flush;
png_write_flush;
png_start_read_image;
png_read_update_info;
png_read_rows;
png_read_row;
png_read_image;
png_write_row;
png_write_rows;
png_write_image;
png_write_end;
png_read_end;
png_destroy_info_struct;
png_destroy_read_struct;
png_destroy_write_struct;
png_set_crc_action;
png_set_filter;
png_set_filter_heuristics;
png_set_compression_level;
png_set_compression_mem_level;
png_set_compression_strategy;
png_set_compression_window_bits;
png_set_compression_method;
png_init_io;
png_set_error_fn;
png_get_error_ptr;
png_set_write_fn;
png_set_read_fn;
png_get_io_ptr;
png_set_read_status_fn;
png_set_write_status_fn;
png_set_mem_fn;
png_get_mem_ptr;
png_set_read_user_transform_fn;
png_set_write_user_transform_fn;
png_set_user_transform_info;
png_get_user_transform_ptr;
png_set_read_user_chunk_fn;
png_get_user_chunk_ptr;
png_set_progressive_read_fn;
png_get_progressive_ptr;
png_process_data;
png_progressive_combine_row;
png_malloc;
png_malloc_warn;
png_free;
png_free_data;
png_data_freer;
png_malloc_default;
png_free_default;
png_memcpy_check;
png_memset_check;
png_error;
png_chunk_error;
png_warning;
png_chunk_warning;
png_get_valid;
png_get_rowbytes;
png_get_rows;
png_set_rows;
png_get_channels;
png_get_image_width;
png_get_image_height;
png_get_bit_depth;
png_get_color_type;
png_get_filter_type;
png_get_interlace_type;
png_get_compression_type;
png_get_pixels_per_meter;
png_get_x_pixels_per_meter;
png_get_y_pixels_per_meter;
png_get_pixel_aspect_ratio;
png_get_x_offset_pixels;
png_get_y_offset_pixels;
png_get_x_offset_microns;
png_get_y_offset_microns;
png_get_signature;
png_get_bKGD;
png_set_bKGD;
png_get_cHRM;
png_get_cHRM_fixed;
png_set_cHRM;
png_set_cHRM_fixed;
png_get_gAMA;
png_get_gAMA_fixed;
png_set_gAMA;
png_set_gAMA_fixed;
png_get_hIST;
png_set_hIST;
png_get_IHDR;
png_set_IHDR;
png_get_oFFs;
png_set_oFFs;
png_get_pCAL;
png_set_pCAL;
png_get_pHYs;
png_set_pHYs;
png_get_PLTE;
png_set_PLTE;
png_get_sBIT;
png_set_sBIT;
png_get_sRGB;
png_set_sRGB;
png_set_sRGB_gAMA_and_cHRM;
png_get_iCCP;
png_set_iCCP;
png_get_sPLT;
png_set_sPLT;
png_get_text;
png_set_text;
png_get_tIME;
png_set_tIME;
png_get_tRNS;
png_set_tRNS;
png_get_sCAL;
png_set_sCAL;
png_set_keep_unknown_chunks;
png_handle_as_unknown;
png_set_unknown_chunks;
png_set_unknown_chunk_location;
png_get_unknown_chunks;
png_set_invalid;
png_read_png;
png_write_png;
png_get_copyright;
png_get_header_ver;
png_get_header_version;
png_get_libpng_ver;
png_permit_mng_features;
png_get_mmx_flagmask;
png_get_asm_flagmask;
png_get_asm_flags;
png_get_mmx_bitdepth_threshold;
png_get_mmx_rowbytes_threshold;
png_set_asm_flags;
png_set_mmx_thresholds;
png_mmx_support;
png_set_strip_error_numbers;
png_set_user_limits;
png_get_user_width_max;
png_get_user_height_max;
png_get_uint_32;
png_get_uint_16;
png_get_int_32;
png_get_uint_31;
png_save_uint_32;
png_save_int_32;
png_save_uint_16;
local: *; };

1
dependencies/libpng/src vendored Submodule

@ -0,0 +1 @@
Subproject commit 6c445538879f9e916f8e62723d2ac7cd77d96191

16
dependencies/libpng/zlib/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,16 @@
project(zlib)
# Silence Warnings
add_compile_options(-w)
## zlib
# Download
set(CMAKE_POLICY_DEFAULT_CMP0022 NEW) # Fix Error
add_subdirectory(src EXCLUDE_FROM_ALL)
# Ensure Build
add_custom_target(zlib-build ALL DEPENDS zlibstatic)
# License
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/zlib")

1
dependencies/libpng/zlib/src vendored Submodule

@ -0,0 +1 @@
Subproject commit 04f42ceca40f73e2978b50e93806c2a18c1281fc

View File

@ -5,10 +5,11 @@ include(FetchContent)
## Minecraft: Pi Edition
# Download
FetchContent_Declare(minecraft-pi
URL "${CMAKE_CURRENT_SOURCE_DIR}/minecraft-pi-0.1.1.tar.gz"
FetchContent_Declare(
minecraft-pi
URL "${CMAKE_CURRENT_SOURCE_DIR}/minecraft-pi-0.1.0.tar.gz"
)
FetchContent_MakeAvailable(minecraft-pi)
FetchContent_Populate(minecraft-pi)
# Install
install(

Binary file not shown.

37
dependencies/qemu/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,37 @@
project(qemu)
## QEMU
# Build
include(ProcessorCount)
ProcessorCount(NPROC)
include(ExternalProject)
ExternalProject_Add(qemu
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src"
CONFIGURE_COMMAND
"${CMAKE_COMMAND}" "-E" "env"
"PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}"
"CFLAGS=-s"
"CXXFLAGS=-s"
"<SOURCE_DIR>/configure"
"--prefix=${CMAKE_INSTALL_PREFIX}"
"--cross-prefix="
"--cc=${CMAKE_C_COMPILER}"
"--cxx=${CMAKE_CXX_COMPILER}"
"--disable-debug-info"
"--target-list=arm-linux-user"
"--without-default-features"
USES_TERMINAL_CONFIGURE TRUE
BUILD_COMMAND "make" "-j${NPROC}" "qemu-arm"
USES_TERMINAL_BUILD TRUE
INSTALL_COMMAND ""
TEST_COMMAND ""
BUILD_BYPRODUCTS "<BINARY_DIR>/qemu-arm"
)
# Install
ExternalProject_Get_property(qemu BINARY_DIR)
install(PROGRAMS "${BINARY_DIR}/qemu-arm" DESTINATION "${MCPI_BIN_DIR}")
# License
install(FILES src/COPYING DESTINATION "${MCPI_LEGAL_DIR}/qemu")

1
dependencies/qemu/src vendored Submodule

@ -0,0 +1 @@
Subproject commit 621da7789083b80d6f1ff1c0fb499334007b4f51

View File

@ -1,12 +0,0 @@
project(runtime)
## Extra Runtime
# Build
add_subdirectory(src)
# RPath
if(TARGET runtime)
set_target_properties(runtime PROPERTIES INSTALL_RPATH "$ORIGIN/../lib/native")
target_link_options(runtime PRIVATE "LINKER:--disable-new-dtags")
endif()

@ -1 +0,0 @@
Subproject commit 84e37b572b55afb1eaa2ada1e37bc36de1584cfd

View File

@ -1,18 +0,0 @@
project(stb_image)
# Silence Warnings
add_compile_options(-w)
## stb_image
# Build
add_library(stb_image SHARED src/stb_image_impl.c)
target_link_libraries(stb_image PRIVATE m)
target_compile_definitions(stb_image PUBLIC STBI_ONLY_PNG)
setup_header_dirs(stb_image "${CMAKE_CURRENT_SOURCE_DIR}/include")
# Install
setup_library(stb_image TRUE TRUE)
# License
install(FILES include/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/stb_image")

@ -1 +0,0 @@
Subproject commit beebb24b945efdea3b9bba23affb8eb3ba8982e7

View File

@ -1,5 +0,0 @@
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image.h"
#include "stb_image_write.h"

View File

@ -1,20 +0,0 @@
project(symbol-processor)
# Install Dependencies
set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(NODE_MODULES "${SRC}/node_modules")
function(npm_run)
execute_process(
COMMAND npm ${ARGV}
WORKING_DIRECTORY "${SRC}"
RESULT_VARIABLE RESULT
)
if(NOT RESULT EQUAL 0)
file(REMOVE_RECURSE "${NODE_MODULES}")
message(FATAL_ERROR "Unable To Run NPM Command")
endif()
endfunction()
if(NOT EXISTS "${NODE_MODULES}")
npm_run(ci --silent)
npm_run(run --silent lint)
endif()

@ -1 +0,0 @@
Subproject commit c803572e248998cc9d197f84661fea56bebf7346

View File

@ -1,12 +0,0 @@
project(utf8cpp)
# Silence Warnings
add_compile_options(-w)
## stb_image
# Build
add_subdirectory(src EXCLUDE_FROM_ALL)
# License
install(FILES src/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/UTF8-CPP")

@ -1 +0,0 @@
Subproject commit f6780f77f6824aa0fbe69f9b97ef7d8aba26ed92

18
dependencies/zenity/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,18 @@
project(zenity)
# Silence Warnings
add_compile_options(-w)
## Zenity
# Download
add_subdirectory(src EXCLUDE_FROM_ALL)
# Ensure Build
add_custom_target(zenity-build ALL DEPENDS zenity)
# Install
install(TARGETS zenity DESTINATION "${MCPI_BIN_DIR}")
# License
install(FILES src/COPYING DESTINATION "${MCPI_LEGAL_DIR}/zenity")

1
dependencies/zenity/src vendored Submodule

@ -0,0 +1 @@
Subproject commit a7496461161c917878d58131711425e7c8e59436

107
docs/ARCHITECTURE.md Normal file
View File

@ -0,0 +1,107 @@
# Architecture
## Launch Sequence
### Common
1. The launcher forks itself.
1. The child process continues the launch sequence.
2. The original process monitors the child process for crashes.
### Client
1. The launcher is started by the user.
1. The launcher starts several Zenity dialogs to configure MCPI-Reborn.
1. If the corresponding environmental variable for a setting is specified, it will be used instead of the dialog.
2. If a setting is cached, then the dialog's default value will be the cached value instead of the normal default.
3. When configuration has been completed, the settings specified will be cached.
2. The launcher replaces itself with MCPI.
1. MCPI-Reborn components are loaded using ``LD_PRELOAD`` and ``LD_LIBRARY_PATH``.
2. If the Media Layer Proxy is enabled, then the Media Layer Proxy Client is started as a sub-process.
### Server
1. The launcher is started by the user.
2. The launcher replaces itself with MCPI.
## Components
### Launcher
This component configures the various environmental variables required for MCPI-Reborn to work. When running in client-mode, this component will also launch several Zenity dialogs for interactive configuration.
The environmental variables configured by this component includes:
* ``LD_PRELOAD``
* ``LD_LIBRARY_PATH``
* ``GCONV_PATH``
* ``MCPI_FEATURE_FLAGS``
* ``MCPI_RENDER_DISTANCE``
* ``MCPI_USERNAME``
This is always compiled for the host system's architecture.
### Media Layer
The Media Layer handles MCPI's graphics calls and user input. It replaces MCPI's native usage of SDL 1.2 with GLFW.
#### Core
This sub-component re-implements a subset of SDL 1.2 calls with GLFW. It also provides a few utility functions that are used internally by MCPI-Reborn.
The utility functions include:
* Fullscreen
* Audio
* Etc
This is always compiled for the host system's architecture unless the Media Layer Proxy is disabled.
This was created because SDL 1.2 has numerous bugs and is in-general unsupported.
#### Proxy
This sub-component must be used if the host system's architecture isn't ARM. It uses UNIX pipes to cross architectural boundaries and allow MCPI to use the Media Layer Core (which is always compiled for the host system's architecture).
It is made of two parts:
* Media Layer Proxy Server
* Links To MCPI
* Creates The UNIX Pipes
* Same External API As The Media Layer Core
* Compiled For ARM
* Media Layer Proxy Client
* Links To The Media Layer Core
* Connects To The Media Layer Proxy Server
* Uses The System's Native GLES Driver (ie. Mesa)
* Compiled For The Host System's Architecture
While proxying all Media Layer Core API calls across UNIX pipes does hurt performance, it is better than emulating the entire graphics stack.
Using this in server-mode is redundant (but is possible).
#### Extras
This sub-component contains code that must always be linked directly to MCPI.
This is always compiled for ARM.
#### Headers
This sub-component includes headers for SDL, GLES, and EGL allowing easy (cross-)compilation.
### Mods
This component patches MCPI to modify its behavior. It's loaded using ``LD_PRELOAD``.
This is always compiled for ARM.
### ``libreborn``
This component contains various utility functions including:
* Code Patching (ARM Only)
* Logging
* Etc
The code patching is ARM only because it relies on hard-coded ARM instructions. However, this is irrelevant since code patching is only needed in ARM code (to patch MCPI).
### ``symbols``
This component contains all MCPI symbols.
## Dependencies
MCPI-Reborn has several dependencies:
* MCPI (Bundled)
* GLFW (Only In Client Mode; Bundled)
* OpenGL ES 2.0
* OpenAL (Only In Client Mode)
* ZLib (Required By LibPNG; Bundled)
* LibPNG (Bundled)
* QEMU User Mode (Only On Non-ARM Hosts; Runtime Only)
* Zenity (Only In Client Mode; Runtime Only; Bundled)

22
docs/BUILDING.md Normal file
View File

@ -0,0 +1,22 @@
# Building
## Dependencies
### Debian/Ubuntu
```sh
./scripts/install-dependencies.sh
```
## Instructions
```sh
./scripts/build.sh <client|server> <armhf|arm64|i686|amd64>
```
### Custom CMake Arguments
```sh
./scripts/setup.sh <client|server> <armhf|arm64|i686|amd64> <Custom CMake Arguments>
./scripts/build.sh <client|server> <armhf|arm64|i686|amd64>
```
### Environment Variables
* ``MCPI_TOOLCHAIN_USE_DEFAULT_SEARCH_PATHS``: Use Default CMake Search Paths Rather Than Guessing

View File

@ -1,158 +1,5 @@
# Changelog
**3.0.0**
* Modding API Revamped
* `*(unsigned char **)` Is Dead!
* Now C++ Only
* Add Peaceful Mode To Options Screen
* Proper Create New World Screen
* Proper Chat Screen
* New Feature Flags
* New Functionality
* `Animated Lava` (Enabled By Default)
* `Animated Fire` (Enabled By Default)
* `Add Cake` (Enabled By Default)
* `Use Java Beta 1.3 Light Ramp` (Enabled By Default)
* `Send Full Level When Hosting Game` (Enabled By Default)
* `Food Overlay` (Disabled By Default)
* `Add Splashes` (Enabled By Default)
* `Display Date In Select World Screen` (Enabled By Default)
* `Optimized Chunk Sorting` (Enabled By Default)
* `Fix Held Item Caching` (Enabled By Default)
* `Add Reborn Info To Options` (Enabled By Default)
* `Log FPS` (Disabled By Default)
* `Add Welcome Screen` (Enabled By Default)
* `F3 Debug Information` (Enabled By Default)
* `Multidraw Rendering` (Enabled By Default)
* `Add Missing Language Strings` (Enabled By Default)
* `Fix Pigmen Burning In The Sun` (Enabled By Default)
* `Fix Carried Grass's Bottom Texture` (Enabled By Default)
* `Hide Crosshair In Third-Person` (Enabled By Default)
* `Fix Camera Legs` (Enabled By Default)
* `Implement Crafting Remainders` (Enabled By Default)
* `Fix Door Duplication` (Enabled By Default)
* `Fix Cobweb Lighting` (Enabled By Default)
* `Fix Sneaking Syncing` (Enabled By Default)
* `Fix Fire Immunity` (Enabled By Default)
* `Fix Fire Syncing` (Enabled By Default)
* `Fix Sunlight Not Properly Setting Mobs On Fire` (Enabled By Default)
* `Stop Creative Players From Burning` (Enabled By Default)
* `Render Fire In Third-Person` (Enabled By Default)
* `Improved Water Rendering` (Enabled By Default)
* `Classic Item Count UI` (Enabled By Default)
* `Allow High-Resolution Title` (Enabled By Default)
* `Improved Classic Title Positioning` (Enabled By Default)
* `Use Updated Title` (Enabled By Default)
* `Hide Block Outline When GUI Is Hidden` (Enabled By Default)
* `Fix Crash When Generating Certain Seeds` (Enabled By Default)
* `Click Buttons On Mouse Down` (Enabled By Default)
* `3D Dropped Items` (Enabled By Default)
* `Render Entity Shadows` (Enabled By Default)
* `Render Vignette` (Enabled By Default)
* `Increase Render Chunk Size` (Enabled By Default)
* `Proper Entity Shading` (Enabled By Default)
* `Fix Sugar Position In Hand` (Enabled By Default)
* `Fix Reloading Textures On Resize` (Enabled By Default)
* `Improved UI Scaling` (Enabled By Default)
* `Text Rendering Fixes` (Enabled By Default)
* `Close Editor When Sign Is Destroyed` (Enabled By Default)
* `Remove Chest Placement Restrictions` (Enabled By Default)
* `Fix Hanging When No Valid Spawn Point Exists` (Enabled By Default)
* `Batch Font Rendering` (Enabled By Default)
* `Fix Furnace Screen Visual Bug` (Enabled By Default)
* `Fix Held Item Poking Through Screen Overlay` (Enabled By Default)
* Existing Functionality (All Enabled By Default)
* `Fix Screen Rendering When Hiding HUD`
* `Sanitize Usernames`
* `Patch RakNet Security Bug`
* `Log RakNet Startup Errors`
* `Prevent Unnecessary Server Pinging`
* `Proper OpenGL Buffer Generation`
* `Fullscreen Support`
* `Always Save Chest Tile Entities`
* `Fix Transferring Durability When Using Items`
* `Fix Switching Perspective While Sneaking`
* `Log Chat Messages`
* `Log Game Status`
* `Screenshot Support`
* `Fix Camera Functionality`
* `Property Scale Animated Textures`
* `Enable Text Input`
* `Update Default Options`
* `Fix options.txt Loading/Saving`
* `Extend Supported Keycodes`
* Split Up `Remove Creative Mode Restrictions` Feature Flag
* `Remove Creative Mode Restrictions` (Disabled By Default)
* `Display Slot Count In Creative Mode` (Disabled By Default)
* `Force Survival Mode Inventory UI` (Disabled By Default)
* `Force Survival Mode Inventory Behavior` (Disabled By Default)
* `Maximize Creative Mode Inventory Stack Size` (Disabled By Default)
* Split Up `Miscellaneous Input Fixes` Feature Flag
* `Fix Escape Key Handling` (Enabled By Default)
* `Stop Locked Mouse From Interacting With HUD` (Enabled By Default)
* Rename Feature Flags
* `Disable Buggy Held Item Caching` To `Fix Held Item Caching`
* `Disable 'gui_blocks' Atlas` To `Regenerate "gui_blocks" Atlas`
* `Fix Sign Placement` To `Enable Sign Screen`
* `Force Touch GUI Inventory` To `Force Touch UI Inventory`
* `Full Touch GUI` To `Full Touch UI`
* `Force Touch GUI Button Behavior` To `Force Touch UI Button Behavior`
* `Remove Forced GUI Lag (Can Break Joining Servers)` To `Remove Forced UI Lag (Can Break Joining Servers)`
* `Hide Block Outline When GUI Is Hidden` To `Hide Block Outline When UI Is Hidden`
* `Fix Camera Functionality` To `Add Camera Functionality`
* `Fix Camera Rendering` To `Enable Camera Rendering`
* `Fix Camera Legs` To `Render Camera Legs`
* Add Milk Buckets
* Included In The `Add Buckets` Feature Flag
* Removed `Property Scale Animated Textures` Feature Flag
* Removed `Remove Invalid Item Background` Feature Flag
* Improve Death Messages
* Massive Build System Improvements
* Fix Item Dropping When Killing Players From The Server Console
* Fix Furnace Visual Bug When Using Lava Bucket As Fuel
* `overwrite_calls` Now Scans VTables
* Unify Server/Client Builds
* Controller Support Removed
* Brand New Launcher UI!
**2.5.3**
* Add `Replace Block Highlight With Outline` Feature Flag (Enabled By Default)
* By Default, The Outline Width Is Set Using The GUI Scale
* This Can Be Overridden Using The `MCPI_BLOCK_OUTLINE_WIDTH` Environmental Variable
* Added `overwrite_calls_within` Function
**2.5.2**
* Add `3D Chest Model` Feature Flag (Enabled By Default)
* Stop Using Jenkins
* Replace `iconv`
* Replace LibPNG
**2.5.1**
* Allow Overriding Custom Skin Server Using `MCPI_SKIN_SERVER` Environmental Variable
* Fix Bug With SDK Generation
**2.5.0**
* [Custom skin support](CUSTOM_SKINS.md)!
* Add `Load Custom Skins` Feature Flag (Enabled By Default)
**2.4.9**
* Allow Overriding GUI Scale With `MCPI_GUI_SCALE` Environmental Variable
* Add `Disable Block Tinting` Feature Flag (Disabled By Default)
* Add `Disable Hostile AI In Creative Mode` Feature Flag (Enabled By Default)
* Allow Accessing Configuration At Runtime (Useful For Mods That Need To Support Multiple Versions)
**2.4.8**
* Fix Bug In `extract_from_bl_instruction`
* Update LIEF And GLFW
* Allow Mods To Access The Original GLFW Keycode For Key Events (But Better)
* More Accurate Sound
**2.4.7**
* Improve Server Performance
* Add `Add Biome Colors To Grass` Feature Flag (Disabled By Default)
* Add `Generate Caves` Feature Flag (Enabled By Default)
* Allow Mods To Access The Original GLFW Keycode For Key Events
**2.4.6**
* [Minimal Controller Support](CONTROLS.md)
* Fix Holding Left-Click When Attacking
@ -164,16 +11,16 @@
**2.4.4**
* Cache Previous Launcher Configuration
* Add `MCPI_API_PORT` Environmental Variable
* Add ``MCPI_API_PORT`` Environmental Variable
* Fix Particles In Front-Facing View
* Fixed Launch Crash On Ubuntu ARM64
* PatchELF Replaced With LIEF
* Moved `3D Anaglyph` Feature Flag To Options Screen
* Add `Improved Classic Title Screen` Feature Flag (Enabled By Default)
* Moved ``3D Anaglyph`` Feature Flag To Options Screen
* Add ``Improved Classic Title Screen`` Feature Flag (Enabled By Default)
* Add Quit button
* Add Options Button (Moved From `Fix Options Screen` Feature Flag)
* Add `Disable Speed Bridging` Feature Flag (Disabled By Default)
* Add `Disable Creative Mode Mining Delay` Feature Flag (Disabled By Default)
* Add Options Button (Moved From ``Fix Options Screen`` Feature Flag)
* Add ``Disable Speed Bridging`` Feature Flag (Disabled By Default)
* Add ``Disable Creative Mode Mining Delay`` Feature Flag (Disabled By Default)
* Improved Feature Flag Names
* Miscellaneous Bug Fixes
* Improved Build System
@ -195,11 +42,11 @@
* More Reliable AppImages
* CMake Refactors
* Disable Broken Touchscreen-Specific Block Outline Behavior
* Add `Remove Forced GUI Lag (Can Break Joining Servers)` Feature Flag (Disabled By Default)
* Add `Add Buckets` Feature Flag (Enabled By Default)
* Add `Classic HUD` Feature Flag (Enabled By Default)
* Add `Translucent Toolbar` Feature Flag (Enabled By Default)
* Add `Force EGL` Feature Flag (Disabled By Default)
* Add ``Remove Forced GUI Lag (Can Break Joining Servers)`` Feature Flag (Disabled By Default)
* Add ``Add Buckets`` Feature Flag (Enabled By Default)
* Add ``Classic HUD`` Feature Flag (Enabled By Default)
* Add ``Translucent Toolbar`` Feature Flag (Enabled By Default)
* Add ``Force EGL`` Feature Flag (Disabled By Default)
* Fix Sound Pitch/Volume/Attenuation
* Fix Holding Left-Click When Attacking
* Don't Force EGL (Should Fix Some NVIDIA Systems)
@ -213,7 +60,7 @@
* Bug Fixes
**2.3.11**
* `--version` Command Line Option
* ``--version`` Command Line Option
* TPS Measured In Benchmark & Server
* Front-Facing Third-Person
* GLESv1 Comparability Layer
@ -239,39 +86,39 @@
* Don't Append Hyphens To New World Name, Only Folder Names
**2.3.6**
* Fix `Invert Y-axis` Option Name
* Fix ``Invert Y-axis`` Option Name
* Improve Touch GUI Inventory In Non-Touch GUI
* New Create World Dialog
* Controlled By `Implement Create World Dialog` Feature Flag (Enabled By Default)
* Controlled By ``Implement Create World Dialog`` Feature Flag (Enabled By Default)
* Custom World Names
* Game-Mode Selection
* Custom Seeds
**2.3.5**
* Renamed Some Feature Flags
* Add `Improved Title Background` Feature Flag (Enabled By Default)
* Add ``Improved Title Background`` Feature Flag (Enabled By Default)
* Non-Touch GUI Rework
* Make `Full Touch GUI` Feature Flag Disabled By Default
* Add `Force Touch GUI Button Behavior` Feature Flag (Enabled By Default)
* Add `Improved Button Hover Behavior` Feature Flag (Enabled By Default)
* Make ``Full Touch GUI`` Feature Flag Disabled By Default
* Add ``Force Touch GUI Button Behavior`` Feature Flag (Enabled By Default)
* Add ``Improved Button Hover Behavior`` Feature Flag (Enabled By Default)
**2.3.4**
* AppImage Fixes
* Make Death Messages Customizable Server-Side
* Fix Q-Key Behavior Behavior When Editing Signs
* Add `Force Touch Inventory` Feature Flag (Disabled By Default)
* Add `Fix Pause Menu` Feature Flag (Enabled By Default)
* Add ``Force Touch Inventory`` Feature Flag (Disabled By Default)
* Add ``Fix Pause Menu`` Feature Flag (Enabled By Default)
* Enables Server Visibility Toggle Button
* Options Changes (Not Supported On Legacy)
* Add `Fix Options Screen` Feature Flag (Enabled By Default)
* Add ``Fix Options Screen`` Feature Flag (Enabled By Default)
* Adds Options Button To Classic UI Start Screen
* Removes Useless Options Toggles
* Fixes Options Toggles' Default Position
* Store Multiple Settings In `options.txt`
* `Peaceful Mode` Feature Flag Moved To `game_difficulty`
* `Smooth Lighting` Feature Flag Moved To `gfx_ao`
* `Fancy Graphics` Feature Flag Moved To `gfx_fancygraphics`
* `Disable Hosting LAN Worlds` Feature Flag Moved To `mp_server_visible_default`
* ``Peaceful Mode`` Feature Flag Moved To ``game_difficulty``
* ``Smooth Lighting`` Feature Flag Moved To ``gfx_ao``
* ``Fancy Graphics`` Feature Flag Moved To ``gfx_fancygraphics``
* ``Disable Hosting LAN Worlds`` Feature Flag Moved To ``mp_server_visible_default``
**2.3.3**
* Add More Blocks To Expanded Creative Inventory
@ -282,31 +129,31 @@
* Add More Blocks To Expanded Creative Inventory
* Fix Nether Reactor With Creative Restrictions Disabled
* Alphabetize Feature Flags
* Add `Disable V-Sync` Feature Flag (Disabled By Default)
* Add ``Disable V-Sync`` Feature Flag (Disabled By Default)
**2.3.1**
* Internal Refactor Of `libreborn`
* Remove Use Of `/bin/sh`
* Internal Refactor Of ``libreborn``
* Remove Use Of ``/bin/sh``
* Load Custom Mods First
* Use Zenity Dark Mode
* Add `Improved Cursor Rendering` Feature Flag (Enabled By Default)
* Add ``Improved Cursor Rendering`` Feature Flag (Enabled By Default)
**2.3.0**
* Switch To AppImage For Packaging
* Prevent OpenAL From Crashing When Out Of Memory
* Vendor GLFW & Zenity
* Seamless Wayland Support
* Add `MCPI_DEBUG` Environmental Variable
* Add `Disable Hosting LAN Worlds` Feature Flag (Disabled By Default)
* Add `Fix Furnace Not Checking Item Auxiliary` Feature Flag (Enabled By Default)
* Add `Disable Raw Mouse Motion (Not Recommended)` Feature Flag (Disabled By Default) For Broken X11 Setups
* Add ``MCPI_DEBUG`` Environmental Variable
* Add ``Disable Hosting LAN Worlds`` Feature Flag (Disabled By Default)
* Add ``Fix Furnace Not Checking Item Auxiliary`` Feature Flag (Enabled By Default)
* Add ``Disable Raw Mouse Motion (Not Recommended)`` Feature Flag (Disabled By Default) For Broken X11 Setups
* Added Back `~/.minecraft-pi/mods`
* Improve Build System
* Improve Documentation
**2.2.11**
* Add `Close Current Screen On Death` Feature Flag (Enabled By Default) To Prevent Bugs
* Fix More Furnace UI Bugs When Using `Disable 'gui_blocks' Atlas`
* Add ``Close Current Screen On Death`` Feature Flag (Enabled By Default) To Prevent Bugs
* Fix More Furnace UI Bugs When Using "Disable 'gui_blocks' Atlas"
**2.2.10**
* Fix Bug With Picking Up Items In "Remove Creative Mode Restrictions" Mode
@ -316,8 +163,8 @@
* Store Files In `/usr/lib`
**2.2.8**
* Add `Hide Chat Messages` Optional Feature Flag
* Add `Remove Creative Mode Restrictions` Optional Feature Flag
* Add ``Hide Chat Messages`` Optional Feature Flag
* Add ``Remove Creative Mode Restrictions`` Optional Feature Flag
* Improve GLFW->SDL Mouse Motion Event Conversion
* Performance Optimizations
* Make Majority Of Server-Specific Logging Code Also Apply To The Client
@ -349,15 +196,15 @@
* Make Missing Sound Event Cause Warning Rather Than Crash
**2.2.1**
* Prevent `random.burp` Sound From Crashing Game
* Prevent ``random.burp`` Sound From Crashing Game
* Always Cleanup Media Layer, Even On Crash
* Resolve All Sounds On Startup
**2.2.0**
* Sound Support
* Split Off `Allow Joining Survival Servers` From Game-Mode Mod
* Split Off ``Allow Joining Survival Servers`` From Game-Mode Mod
* Separate Headless Code From Server Code
* Fix Bug Where `RakNetInstance` Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
* Fix Bug Where ``RakNetInstance`` Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
* Clean-Up Code
* Remove Support For Debian Buster
@ -374,7 +221,7 @@
* Print Error Message If RakNet Fails To Start
**2.1.4**
* Fix `RakNet::RakString` Security Bug
* Fix ``RakNet::RakString`` Security Bug
**2.1.3**
* Workaround Broken Library Search Path On Some ARM 32-Bit Systems
@ -386,16 +233,16 @@
* Fix Symlink Code
**2.1.0**
* Allow Binding `Q` Key To Item Dropping
* Allow Binding ``Q`` Key To Item Dropping
* Expose More Feature Flags
* Replace `Mob Spawning` Feature Flag With `Force Mob Spawning`
* Fix `ESC` Key In Options Menu When `Miscellaneous Input Fixes` Is Enabled
* Replace ``Mob Spawning`` Feature Flag With ``Force Mob Spawning``
* Fix ``ESC`` Key In Options Menu When ``Miscellaneous Input Fixes`` Is Enabled
**2.0.9**
* Fix Translucent Preview Items In Furnace UI Being Fully Opaque When The `gui_blocks` Atlas Is Disabled
* Fix Translucent Preview Items In Furnace UI Being Fully Opaque When The ``gui_blocks`` Atlas Is Disabled
**2.0.8**
* Use Default Port In `servers.txt` If Not Specified
* Use Default Port In ``servers.txt`` If Not Specified
**2.0.7**
* Fix Sign Text Not Updating In Multiplayer When Exiting Editing UI Using Escape Button
@ -412,7 +259,7 @@
* Optimize Media Layer Proxy
**2.0.3**
* Make `kill` Admin Command Print Death Message
* Make ``kill`` Admin Command Print Death Message
**2.0.2**
* Fix Mouse Cursor Bugs

61
docs/COMMAND_LINE.md Normal file
View File

@ -0,0 +1,61 @@
# Command Line Usage
## Command Line Arguments
### ``--version`` (Or ``-v``)
If you run MCPI-Reborn with ``--version`` it will print its version to ``stdout``.
### ``--debug``
This sets ``MCPI_DEBUG``.
### Client Mode Only
#### ``--print-available-feature-flags``
This print the available feature flags (and their default values) to ``stdout`` and then immediately exit.
The feature flags are printed in the following format:
```
TRUE This Flag Is On By Default
FALSE This Flag Is Off By Default
```
#### ``--default``
This will skip the startup configuration dialogs and just use the default values. This will use the cached configuration unless ``--no-cache`` is used.
#### ``--benchmark``
This will make MCPI-Reborn enter a simple benchmark mode. This means automatically loading a newly generated world, then rotating the camera for a period of time. When it has finished, it will then exit and print the average FPS while the world was loaded. In this mode, all user input is blocked. However you can still modify rendering settings by changing feature flags.
The world used will always be re-created on start and uses a hard-coded seed.
#### ``--no-cache``
This will skip loading and saving the cached launcher configuration.
#### ``--wipe-cache``
This will wipe the cached launcher configuration.
### Server Mode Only
#### ``--only-generate``
This will make MCPI-Reborn immediately exit once world generation has completed. This is mainly used for automatically testing MCPI-Reborn.
## Environmental Variables
### ``MCPI_DEBUG``
This enables debug logging if it is set.
### ``MCPI_API_PORT``
This configures the API to use a different port (the default is 4711).
### Client Mode Only
If any of the following variables aren't set, one configuration dialog will open on startup for each unset variable.
#### ``MCPI_FEATURE_FLAGS``
This corresponds to ``--print-available-feature-flags``. This is just a list of all enabled feature flags separated by ``|``.
For instance, the string ``Feature A|Feature B`` would enable both ``Feature A`` and ``Feature B`` and *disable every other available feature flag*.
#### ``MCPI_RENDER_DISTANCE``
This is the render distance. The possible values are: ``Far``, ``Normal``, ``Short``, and ``Tiny``.
#### ``MCPI_USERNAME``
This is the username.

View File

@ -24,3 +24,22 @@
| Scroll Wheel | Cycle Selected Item In Toolbar |
| Left-CLick | Attack/Destroy |
| Right-Click | Use Item/Place Block |
## Game Controller
| Action | Function |
| --- | --- |
| A | Jump |
| Y | Open Inventory |
| B | Sneak[^1] |
| X | Open Crafting |
| D-Pad Up | Change Perspective |
| D-Pad Down | Drop Item |
| D-Pad Right | Open Chat |
| Left/Right Bumper | Cycle Selected Item In Toolbar |
| Left Trigger | Use Item/Place Block |
| Right Trigger | Attack/Destroy |
| Start/Back | Pause |
| Left Stick | Movement |
| Right Stick | Camera Control |
[^1]: Unlike Minecraft: Bedrock Edition, this *is not* a toggle.

View File

@ -8,4 +8,3 @@
| [RetDec](https://retdec.com) | Used For Decompiling Minecraft: Pi Edition |
| [minecraft-linux/mcpelauncher-core](https://github.com/minecraft-linux/mcpelauncher-core/blob/6b5e17b5685a612143297ae4595bdd12327284f3/src/patch_utils.cpp#L42) | Original Function Overwrite Code |
| [Hooking C Functions at Runtime - Thomas Finch](http://thomasfinch.me/blog/2015/07/24/Hooking-C-Functions-At-Runtime.html) | Original Patching Code |
| [ReMinecraftPE](https://github.com/ReMinecraftPE/mcpe) | A Lot Of Decompiled Code |

View File

@ -1,6 +0,0 @@
# Custom Skins
MCPI-Reborn supports downloading custom skins from [a central skin server](https://github.com/MCPI-Revival/Skins). Skins are downloaded based on the current MCPI username.
This *does not* cache skins and *will not* work without internet access.
Custom skins can be disabled using the `Load Custom Skins` feature flag.

View File

@ -1,14 +1,19 @@
# Dedicated Server
The dedicated server is a version of Minecraft: Pi Edition modified to run in a headless environment. It loads settings from a `server.properties` file.
The dedicated server is a version of Minecraft: Pi Edition modified to run in a headless environment. It loads settings from a ``server.properties`` file.
This server is also compatible with MCPE Alpha v0.6.1[^1].
This server is also compatible with MCPE Alpha v0.5.0[^1].
## Setup
To use, run the normal AppImage with the `--server` argument. It will generate the world and `server.properties` in the current directory.
### Debian Package
To use, install and run ``minecraft-pi-reborn-legacy-server``. It will generate the world and ``server.properties`` in the current directory.
### Docker Image
An official Docker image is also provided: [thebrokenrail/minecraft-pi-reborn-legacy-server](https://hub.docker.com/r/thebrokenrail/minecraft-pi-reborn-legacy-server).
## Server Limitations
* Player data is not saved because of limitations with MCPE LAN worlds
* An easy workaround is to place your inventory in a chest before logging off
* Survival Mode servers are incompatible with un-modded MCPI
* Survival Mode servers are incompatible with unmodded MCPI
[^1]: The exception to this is buckets and other modded items, those will crash MCPE players.
[^1]: The exception to this is buckets, those will crash MCPE players.

View File

@ -1,70 +0,0 @@
---
gitea: none
include_toc: true
---
# Getting Started
Welcome to the official guide for setting up Minecraft: Pi Edition: Reborn (also known as MCPI-Reborn)! This document will help you through the installation and setup process.
## System Requirements
MCPI-Reborn requires support for OpenGL ES v2.0 (unlike the original game, which used OpenGL ES v1.1). It also only supports Linux-based systems.
In addition, while the original game could only be run on the Raspberry Pi, MCPI-Reborn is much more flexible. It supports running on 32-bit ARM (known as `armhf`), 64-bit ARM (known as `arm64`), and 64-bit x86 (known as `amd64`).
## Installation
There are three supported ways to install MCPI-Reborn.
### AppImage
The first supported way to install MCPI-Reborn is with an [AppImage](https://appimage.org). An AppImage is a portable application format that allows users to run software without installation.
To run MCPI-Reborn, all you need to do is [download the latest AppImage](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases/latest) for your architecture and run it.
More details can be found [here](https://docs.appimage.org/introduction/quickstart.html#how-to-run-an-appimage).
<details>
<summary><b>Additional System Requirements</b></summary>
The AppImage requires Debian Bullseye or higher. This is equivalent to Ubuntu 20.04.
It also requires some additional packages. To install them, run:
```sh
sudo apt install -y libopenal1 libglib2.0-0
```
</details>
### Flatpak
The next method is the official [Flatpak](https://www.flatpak.org/). This method has the additional benefit of built-in sandboxing. Unfortunately, it does not support 32-bit ARM systems.
It can be installed through [Flathub](https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn).
### Pi-Apps
The final supported method is [Pi-Apps](https://github.com/Botspot/pi-apps). It is a ["well-maintained collection of app installation-scripts"](https://github.com/Botspot/pi-apps#:~:text=well-maintained%20collection%20of%20app%20installation-scripts) that includes support for MCPI-Reborn.
The list of systems supported by Pi-Apps can be found [here](https://github.com/Botspot/pi-apps?tab=readme-ov-file#supported-systems).
## Managing Game Data
Just as regular Minecraft stores game data at `~/.minecraft`, MCPI-Reborn uses `~/.minecraft-pi`[^1]. This is the profile directory and is where your worlds, screenshots, and game settings are stored.
The profile directory can easily be accessed by opening MCPI-Reborn and going to `Options -> Reborn -> Profile Directory`.
## Sound
One of MCPI-Reborn's most important modifications is the addition of a sound engine. However, due to copyright limitations, Minecraft's sounds cannot be distributed with MCPI-Reborn and must be installed manually.
Fortunately, installing the sound data is simple:
1. Obtain a valid Minecraft: Pocket Edition v0.6.1[^2] APK file.
2. Extract `lib/*/libminecraftpe.so` from the APK.
3. Create the directory `<Profile Directory>/overrides` if it does not already exist.
4. Copy `libminecraftpe.so` into `<Profile Directory>/overrides`.
5. Sound should now be fully functional!
## Custom Textures
MCPI-Reborn allows users to easily use custom textures through the use of an "overrides directory." Any files placed in this directory will automatically replace their equivalent file in MCPI-Reborn.
For instance, to override `data/images/terrain.png`, you would copy the replacement file to `<Overrides Folder>/images/terrain.png`.
The overrides directory is located at `<Profile Directory>/overrides`.
## Discord
If you have any questions or just want to talk about Minecraft: Pi Edition, there is an [official Discord server](https://discord.com/invite/aDqejQGMMy)!
[^1]: When using the Flatpak, the profile directory is located at `~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi`.
[^2]: This is not a strict requirement; a Minecraft: Pocket Edition v0.8.1 APK would likely work, but it is not guaranteed.

24
docs/INSTALL.md Normal file
View File

@ -0,0 +1,24 @@
# Installation
## AppImage
Download packages [here](https://jenkins.thebrokenrail.com/job/minecraft-pi-reborn/job/legacy/lastSuccessfulBuild/artifact/out/).
### System Requirements
* Debian Buster/Ubuntu 18.04 Or Higher
* Client-Only Dependencies
* Graphics Drivers
* GTK+ 3
* Debian/Ubuntu: ``sudo apt install libgtk-3-0``
* Arch: ``sudo pacman -S gtk3``
* OpenAL
* Debian/Ubuntu: ``sudo apt install libopenal1``
* Arch: ``sudo pacman -S openal``
### Running
Follow [these](https://docs.appimage.org/introduction/quickstart.html#how-to-run-an-appimage) instructions.
## Flatpak
<a href="https://flathub.org/apps/details/com.thebrokenrail.MCPIReborn"><img width="240" alt="Download On Flathub" src="https://flathub.org/assets/badges/flathub-badge-en.svg" /></a>
### Note
Game data is stored in ``~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi`` instead of ``~/.minecraft-pi``.

16
docs/MULTIPLAYER.md Normal file
View File

@ -0,0 +1,16 @@
# Multiplayer
MCPI-Reborn supports two ways to play multiplayer.
## Local Network (LAN)
This is also supported by vanilla MCPI. Just load a world in MCPI and other devices on the network can join.
## External Servers
Unlike vanilla MCPI, MCPI-Reborn allows you to natively join a server outside of the local network. Just modify ``~/.minecraft-pi/servers.txt`` and it should show up in MCPI's server list.
### Example ``~/.minecraft-pi/servers.txt``
```
# Default Port Is 19132
example.com
# Custom Port
example.com:19133
```

View File

@ -0,0 +1,6 @@
# Overriding Assets
To make overriding assets easier, MCPI-Reborn provides an overrides folder. Any file located in Minecraft: Pi Edition's ``data`` folder can be overridden by placing a file with the same name and path in the overrides folder. The overrides folder is located at ``~/.minecraft-pi/overrides``.
## Examples
- ``data/images/terrain.png`` -> ``~/.minecraft-pi/overrides/images/terrain.png``
- ``data/lang/en_US.lang`` -> ``~/.minecraft-pi/overrides/lang/en_US.lang``

View File

@ -1,8 +1,13 @@
# Documentation
* [View Getting Started](GETTING_STARTED.md)
* [View Installation](INSTALL.md)
* [View Overriding Assets](OVERRIDING_ASSETS.md)
* [View Dedicated Server](DEDICATED_SERVER.md)
* [View Credits](CREDITS.md)
* [View Terminology](TERMINOLOGY.md)
* [View Building](BUILDING.md)
* [View Architecture](ARCHITECTURE.md)
* [View Command Line Arguments](COMMAND_LINE.md)
* [View Multiplayer](MULTIPLAYER.md)
* [View Sound](SOUND.md)
* [View In-Game Controls](CONTROLS.md)
* [View Custom Skins](CUSTOM_SKINS.md)
* [View Changelog](CHANGELOG.md)

7
docs/SOUND.md Normal file
View File

@ -0,0 +1,7 @@
# Sound
One of MCPI-Reborn's main modifications is a sound-engine since MCPI doesn't include one by default[^1]. However, it can't be used out-of-box because MCPI doesn't contain any sound data and MCPI-Reborn can't include it because of copyright.
MCPE's sound data can be extracted from any MCPE v0.5.0[^2] APK file, just place its `libminecraftpe.so` into `~/.minecraft-pi/overrides` and you should have sound!
[^1]: The mute button is just leftover code from MCPE, it doesn't actually do anything in un-modded MCPI, however it is connected to MCPI-Reborn's sound-engine.
[^2]: This isn't a hard limit, an MCPE v0.8.1 APK would probably work, but don't rely on it.

View File

@ -1,11 +1,19 @@
# Example Mods
These are example mods that can be built using the modding SDK.
This is an example of a mod that can be built using the modding SDK.
* **Expanded Creative Mod**: This specific mod adds even more items and blocks to the Creative Inventory. It was originally by [@Bigjango13](https://github.com/bigjango13).
* **Chat Commands Mod**: This specific mod makes a chat message starting with `/` handled by the MCPI API.
* **Chat Commands Mod**: This specific mod makes an chat message starting with a ``/`` handled by the MCPI API.
* **Recipes Mod**: This specific mod demos custom recipes.
## The SDK
The modding SDK is a collection of exported CMake targets that allows anyone to create their own MCPI mod!
The SDK is copied to `~/.minecraft-pi/sdk` whenever MCPI-Reborn is started.
The SDK is copied to ``~/.minecraft-pi/sdk/lib/minecraft-pi-reborn-legacy-client/sdk/sdk.cmake`` whenever MCPI-Reborn is started.
## How do I use this?
```sh
mkdir build
cd build
cmake ..
cp libexpanded-creative.so ~/.minecraft-pi/legacy-mods
```

View File

@ -1,26 +0,0 @@
#!/bin/sh
set -e
# Create Output Directory
cd "$(dirname "$0")"
ROOT="$(pwd)"
OUT="${ROOT}/out"
rm -rf "${OUT}"
mkdir -p "${OUT}"
# Build
build() {
cd "${ROOT}/$1"
# Build
rm -rf build
mkdir build
cd build
cmake -GNinja ..
cmake --build .
# Copy Result
cp lib*.so "${OUT}"
}
build chat-commands
build expanded-creative
build recipes

View File

@ -3,15 +3,13 @@ cmake_minimum_required(VERSION 3.16.0)
# Build For ARM
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "arm")
# Start Project
project(chat-commands)
# Include SDK
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn/sdk/sdk.cmake")
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-legacy-client/sdk/sdk.cmake")
# Build
add_library(chat-commands SHARED chat-commands.cpp)
target_link_libraries(chat-commands mods reborn-patch symbols)
target_link_libraries(chat-commands mods-headers reborn-patch symbols chat misc)

View File

@ -1,45 +1,25 @@
#include <libreborn/patch.h>
#include <libreborn/util/util.h>
#include <libreborn/util/string.h>
// Headers
#include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#include <mods/chat/chat.h>
#include <mods/misc/misc.h>
#include <mods/server/server.h>
// The Actual Mod
HOOK(chat_handle_packet_send, void, (const Minecraft *minecraft, ChatPacket *packet)) {
HOOK(chat_handle_packet_send, void, (unsigned char *minecraft, unsigned char *packet)) {
// Get Message
const char *message = packet->message.c_str();
char *message = *(char **) (packet + ChatPacket_message_property_offset);
if (message[0] == '/') {
// API Command
Minecraft *mc = (Minecraft *) minecraft;
Gui *gui = &mc->gui;
std::string out = chat_send_api_command(mc, (char *) &message[1]);
unsigned char *gui = minecraft + Minecraft_gui_property_offset;
std::string out = chat_send_api_command(minecraft, &message[1]);
if (out.length() > 0 && out[out.length() - 1] == '\n') {
out[out.length() - 1] = '\0';
}
std::string cp437_out = to_cp437(out);
gui->addMessage(cp437_out);
misc_add_message(gui, out.c_str());
} else {
// Call Original Method
real_chat_handle_packet_send()(minecraft, packet);
ensure_chat_handle_packet_send();
(*real_chat_handle_packet_send)(minecraft, packet);
}
}
// Add Server Command
HOOK(server_get_commands, std::vector<ServerCommand> *, (Minecraft *minecraft, ServerSideNetworkHandler *server_side_network_handler)) {
// Call Original Method
std::vector<ServerCommand> *commands = real_server_get_commands()(minecraft, server_side_network_handler);
// Add Command
commands->push_back({
.name = "greet",
.comment = "Example Custom Command",
.callback = [](__attribute__((unused)) const std::string &cmd) {
INFO("Hello World!");
}
});
// Return
return commands;
}

View File

@ -3,15 +3,13 @@ cmake_minimum_required(VERSION 3.16.0)
# Build For ARM
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "arm")
# Start Project
project(expanded-creative)
# Include SDK
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn/sdk/sdk.cmake")
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-legacy-client/sdk/sdk.cmake")
# Build
add_library(expanded-creative SHARED expanded-creative.cpp)
target_link_libraries(expanded-creative mods reborn-patch symbols)
target_link_libraries(expanded-creative mods-headers reborn-patch symbols misc)

View File

@ -1,544 +1,494 @@
#include <libreborn/patch.h>
// Headers
#include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#include <mods/misc/misc.h>
// The Actual Mod
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(FillingContainer *filling_container) {
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(unsigned char *filling_container) {
ItemInstance *fire_instance = new ItemInstance;
ALLOC_CHECK(fire_instance);
fire_instance->count = 255;
fire_instance->auxiliary = 0;
fire_instance->id = 51;
filling_container->addItem(fire_instance);
(*FillingContainer_addItem)(filling_container, fire_instance);
ItemInstance *mushroomStew_instance = new ItemInstance;
ALLOC_CHECK(mushroomStew_instance);
mushroomStew_instance->count = 255;
mushroomStew_instance->auxiliary = 0;
mushroomStew_instance->id = 282;
filling_container->addItem(mushroomStew_instance);
(*FillingContainer_addItem)(filling_container, mushroomStew_instance);
ItemInstance *steak_instance = new ItemInstance;
ALLOC_CHECK(steak_instance);
steak_instance->count = 255;
steak_instance->auxiliary = 0;
steak_instance->id = 364;
filling_container->addItem(steak_instance);
(*FillingContainer_addItem)(filling_container, steak_instance);
ItemInstance *cookedChicken_instance = new ItemInstance;
ALLOC_CHECK(cookedChicken_instance);
cookedChicken_instance->count = 255;
cookedChicken_instance->auxiliary = 0;
cookedChicken_instance->id = 366;
filling_container->addItem(cookedChicken_instance);
(*FillingContainer_addItem)(filling_container, cookedChicken_instance);
ItemInstance *porkCooked_instance = new ItemInstance;
ALLOC_CHECK(porkCooked_instance);
porkCooked_instance->count = 255;
porkCooked_instance->auxiliary = 0;
porkCooked_instance->id = 320;
filling_container->addItem(porkCooked_instance);
(*FillingContainer_addItem)(filling_container, porkCooked_instance);
ItemInstance *apple_instance = new ItemInstance;
ALLOC_CHECK(apple_instance);
apple_instance->count = 255;
apple_instance->auxiliary = 0;
apple_instance->id = 260;
filling_container->addItem(apple_instance);
(*FillingContainer_addItem)(filling_container, apple_instance);
ItemInstance *tallGrass_instance = new ItemInstance;
ALLOC_CHECK(tallGrass_instance);
tallGrass_instance->count = 255;
tallGrass_instance->auxiliary = 0;
tallGrass_instance->id = 31;
filling_container->addItem(tallGrass_instance);
(*FillingContainer_addItem)(filling_container, tallGrass_instance);
ItemInstance *crops_instance = new ItemInstance;
ALLOC_CHECK(crops_instance);
crops_instance->count = 255;
crops_instance->auxiliary = 0;
crops_instance->id = 59;
filling_container->addItem(crops_instance);
(*FillingContainer_addItem)(filling_container, crops_instance);
ItemInstance *farmland_instance = new ItemInstance;
ALLOC_CHECK(farmland_instance);
farmland_instance->count = 255;
farmland_instance->auxiliary = 0;
farmland_instance->id = 60;
filling_container->addItem(farmland_instance);
(*FillingContainer_addItem)(filling_container, farmland_instance);
ItemInstance *activeFurnace_instance = new ItemInstance;
ALLOC_CHECK(activeFurnace_instance);
activeFurnace_instance->count = 255;
activeFurnace_instance->auxiliary = 0;
activeFurnace_instance->id = 62;
filling_container->addItem(activeFurnace_instance);
(*FillingContainer_addItem)(filling_container, activeFurnace_instance);
ItemInstance *ironDoor_instance = new ItemInstance;
ALLOC_CHECK(ironDoor_instance);
ironDoor_instance->count = 255;
ironDoor_instance->auxiliary = 0;
ironDoor_instance->id = 330;
filling_container->addItem(ironDoor_instance);
(*FillingContainer_addItem)(filling_container, ironDoor_instance);
ItemInstance *activeRedstoneOre_instance = new ItemInstance;
ALLOC_CHECK(activeRedstoneOre_instance);
activeRedstoneOre_instance->count = 255;
activeRedstoneOre_instance->auxiliary = 0;
activeRedstoneOre_instance->id = 74;
filling_container->addItem(activeRedstoneOre_instance);
(*FillingContainer_addItem)(filling_container, activeRedstoneOre_instance);
ItemInstance *pumkinStem_instance = new ItemInstance;
ALLOC_CHECK(pumkinStem_instance);
pumkinStem_instance->count = 255;
pumkinStem_instance->auxiliary = 0;
pumkinStem_instance->id = 105;
filling_container->addItem(pumkinStem_instance);
(*FillingContainer_addItem)(filling_container, pumkinStem_instance);
ItemInstance *newGrass_instance = new ItemInstance;
ALLOC_CHECK(newGrass_instance);
newGrass_instance->count = 255;
newGrass_instance->auxiliary = 0;
newGrass_instance->id = 253;
filling_container->addItem(newGrass_instance);
(*FillingContainer_addItem)(filling_container, newGrass_instance);
ItemInstance *reserved6_instance = new ItemInstance;
ALLOC_CHECK(reserved6_instance);
reserved6_instance->count = 255;
reserved6_instance->auxiliary = 0;
reserved6_instance->id = 1;
filling_container->addItem(reserved6_instance);
(*FillingContainer_addItem)(filling_container, reserved6_instance);
ItemInstance *doubleStoneSlab_instance = new ItemInstance;
ALLOC_CHECK(doubleStoneSlab_instance);
doubleStoneSlab_instance->count = 255;
doubleStoneSlab_instance->auxiliary = 0;
doubleStoneSlab_instance->id = 43;
filling_container->addItem(doubleStoneSlab_instance);
(*FillingContainer_addItem)(filling_container, doubleStoneSlab_instance);
ItemInstance *arrow_instance = new ItemInstance;
ALLOC_CHECK(arrow_instance);
arrow_instance->count = 255;
arrow_instance->auxiliary = 0;
arrow_instance->id = 262;
filling_container->addItem(arrow_instance);
(*FillingContainer_addItem)(filling_container, arrow_instance);
ItemInstance *coal_instance = new ItemInstance;
ALLOC_CHECK(coal_instance);
coal_instance->count = 255;
coal_instance->auxiliary = 0;
coal_instance->id = 263;
filling_container->addItem(coal_instance);
(*FillingContainer_addItem)(filling_container, coal_instance);
ItemInstance *diamond_instance = new ItemInstance;
ALLOC_CHECK(diamond_instance);
diamond_instance->count = 255;
diamond_instance->auxiliary = 0;
diamond_instance->id = 264;
filling_container->addItem(diamond_instance);
(*FillingContainer_addItem)(filling_container, diamond_instance);
ItemInstance *ironIngot_instance = new ItemInstance;
ALLOC_CHECK(ironIngot_instance);
ironIngot_instance->count = 255;
ironIngot_instance->auxiliary = 0;
ironIngot_instance->id = 265;
filling_container->addItem(ironIngot_instance);
(*FillingContainer_addItem)(filling_container, ironIngot_instance);
ItemInstance *goldIngot_instance = new ItemInstance;
ALLOC_CHECK(goldIngot_instance);
goldIngot_instance->count = 255;
goldIngot_instance->auxiliary = 0;
goldIngot_instance->id = 266;
filling_container->addItem(goldIngot_instance);
(*FillingContainer_addItem)(filling_container, goldIngot_instance);
ItemInstance *woodSword_instance = new ItemInstance;
ALLOC_CHECK(woodSword_instance);
woodSword_instance->count = 255;
woodSword_instance->auxiliary = 0;
woodSword_instance->id = 268;
filling_container->addItem(woodSword_instance);
(*FillingContainer_addItem)(filling_container, woodSword_instance);
ItemInstance *woodShovel_instance = new ItemInstance;
ALLOC_CHECK(woodShovel_instance);
woodShovel_instance->count = 255;
woodShovel_instance->auxiliary = 0;
woodShovel_instance->id = 269;
filling_container->addItem(woodShovel_instance);
(*FillingContainer_addItem)(filling_container, woodShovel_instance);
ItemInstance *woodPickaxe_instance = new ItemInstance;
ALLOC_CHECK(woodPickaxe_instance);
woodPickaxe_instance->count = 255;
woodPickaxe_instance->auxiliary = 0;
woodPickaxe_instance->id = 270;
filling_container->addItem(woodPickaxe_instance);
(*FillingContainer_addItem)(filling_container, woodPickaxe_instance);
ItemInstance *woodAxe_instance = new ItemInstance;
ALLOC_CHECK(woodAxe_instance);
woodAxe_instance->count = 255;
woodAxe_instance->auxiliary = 0;
woodAxe_instance->id = 271;
filling_container->addItem(woodAxe_instance);
(*FillingContainer_addItem)(filling_container, woodAxe_instance);
ItemInstance *stoneSword_instance = new ItemInstance;
ALLOC_CHECK(stoneSword_instance);
stoneSword_instance->count = 255;
stoneSword_instance->auxiliary = 0;
stoneSword_instance->id = 272;
filling_container->addItem(stoneSword_instance);
(*FillingContainer_addItem)(filling_container, stoneSword_instance);
ItemInstance *stoneShovel_instance = new ItemInstance;
ALLOC_CHECK(stoneShovel_instance);
stoneShovel_instance->count = 255;
stoneShovel_instance->auxiliary = 0;
stoneShovel_instance->id = 273;
filling_container->addItem(stoneShovel_instance);
(*FillingContainer_addItem)(filling_container, stoneShovel_instance);
ItemInstance *stonePickaxe_instance = new ItemInstance;
ALLOC_CHECK(stonePickaxe_instance);
stonePickaxe_instance->count = 255;
stonePickaxe_instance->auxiliary = 0;
stonePickaxe_instance->id = 274;
filling_container->addItem(stonePickaxe_instance);
(*FillingContainer_addItem)(filling_container, stonePickaxe_instance);
ItemInstance *stoneAxe_instance = new ItemInstance;
ALLOC_CHECK(stoneAxe_instance);
stoneAxe_instance->count = 255;
stoneAxe_instance->auxiliary = 0;
stoneAxe_instance->id = 275;
filling_container->addItem(stoneAxe_instance);
(*FillingContainer_addItem)(filling_container, stoneAxe_instance);
ItemInstance *shovelIron_instance = new ItemInstance;
ALLOC_CHECK(shovelIron_instance);
shovelIron_instance->count = 255;
shovelIron_instance->auxiliary = 0;
shovelIron_instance->id = 256;
filling_container->addItem(shovelIron_instance);
(*FillingContainer_addItem)(filling_container, shovelIron_instance);
ItemInstance *ironPick_instance = new ItemInstance;
ALLOC_CHECK(ironPick_instance);
ironPick_instance->count = 255;
ironPick_instance->auxiliary = 0;
ironPick_instance->id = 257;
filling_container->addItem(ironPick_instance);
(*FillingContainer_addItem)(filling_container, ironPick_instance);
ItemInstance *ironAxe_instance = new ItemInstance;
ALLOC_CHECK(ironAxe_instance);
ironAxe_instance->count = 255;
ironAxe_instance->auxiliary = 0;
ironAxe_instance->id = 258;
filling_container->addItem(ironAxe_instance);
(*FillingContainer_addItem)(filling_container, ironAxe_instance);
ItemInstance *diamondSword_instance = new ItemInstance;
ALLOC_CHECK(diamondSword_instance);
diamondSword_instance->count = 255;
diamondSword_instance->auxiliary = 0;
diamondSword_instance->id = 276;
filling_container->addItem(diamondSword_instance);
(*FillingContainer_addItem)(filling_container, diamondSword_instance);
ItemInstance *diamondShovel_instance = new ItemInstance;
ALLOC_CHECK(diamondShovel_instance);
diamondShovel_instance->count = 255;
diamondShovel_instance->auxiliary = 0;
diamondShovel_instance->id = 277;
filling_container->addItem(diamondShovel_instance);
(*FillingContainer_addItem)(filling_container, diamondShovel_instance);
ItemInstance *diamondPickaxe_instance = new ItemInstance;
ALLOC_CHECK(diamondPickaxe_instance);
diamondPickaxe_instance->count = 255;
diamondPickaxe_instance->auxiliary = 0;
diamondPickaxe_instance->id = 278;
filling_container->addItem(diamondPickaxe_instance);
(*FillingContainer_addItem)(filling_container, diamondPickaxe_instance);
ItemInstance *diamondAxe_instance = new ItemInstance;
ALLOC_CHECK(diamondAxe_instance);
diamondAxe_instance->count = 255;
diamondAxe_instance->auxiliary = 0;
diamondAxe_instance->id = 279;
filling_container->addItem(diamondAxe_instance);
(*FillingContainer_addItem)(filling_container, diamondAxe_instance);
ItemInstance *magicWand_instance = new ItemInstance;
ALLOC_CHECK(magicWand_instance);
magicWand_instance->count = 255;
magicWand_instance->auxiliary = 0;
magicWand_instance->id = 280;
filling_container->addItem(magicWand_instance);
(*FillingContainer_addItem)(filling_container, magicWand_instance);
ItemInstance *bowl_instance = new ItemInstance;
ALLOC_CHECK(bowl_instance);
bowl_instance->count = 255;
bowl_instance->auxiliary = 0;
bowl_instance->id = 281;
filling_container->addItem(bowl_instance);
(*FillingContainer_addItem)(filling_container, bowl_instance);
ItemInstance *goldSword_instance = new ItemInstance;
ALLOC_CHECK(goldSword_instance);
goldSword_instance->count = 255;
goldSword_instance->auxiliary = 0;
goldSword_instance->id = 283;
filling_container->addItem(goldSword_instance);
(*FillingContainer_addItem)(filling_container, goldSword_instance);
ItemInstance *goldShovel_instance = new ItemInstance;
ALLOC_CHECK(goldShovel_instance);
goldShovel_instance->count = 255;
goldShovel_instance->auxiliary = 0;
goldShovel_instance->id = 284;
filling_container->addItem(goldShovel_instance);
(*FillingContainer_addItem)(filling_container, goldShovel_instance);
ItemInstance *goldPickaxe_instance = new ItemInstance;
ALLOC_CHECK(goldPickaxe_instance);
goldPickaxe_instance->count = 255;
goldPickaxe_instance->auxiliary = 0;
goldPickaxe_instance->id = 285;
filling_container->addItem(goldPickaxe_instance);
(*FillingContainer_addItem)(filling_container, goldPickaxe_instance);
ItemInstance *goldAxe_instance = new ItemInstance;
ALLOC_CHECK(goldAxe_instance);
goldAxe_instance->count = 255;
goldAxe_instance->auxiliary = 0;
goldAxe_instance->id = 286;
filling_container->addItem(goldAxe_instance);
(*FillingContainer_addItem)(filling_container, goldAxe_instance);
ItemInstance *string_instance = new ItemInstance;
ALLOC_CHECK(string_instance);
string_instance->count = 255;
string_instance->auxiliary = 0;
string_instance->id = 287;
filling_container->addItem(string_instance);
(*FillingContainer_addItem)(filling_container, string_instance);
ItemInstance *feather_instance = new ItemInstance;
ALLOC_CHECK(feather_instance);
feather_instance->count = 255;
feather_instance->auxiliary = 0;
feather_instance->id = 288;
filling_container->addItem(feather_instance);
(*FillingContainer_addItem)(filling_container, feather_instance);
ItemInstance *gunpowder_instance = new ItemInstance;
ALLOC_CHECK(gunpowder_instance);
gunpowder_instance->count = 255;
gunpowder_instance->auxiliary = 0;
gunpowder_instance->id = 289;
filling_container->addItem(gunpowder_instance);
(*FillingContainer_addItem)(filling_container, gunpowder_instance);
ItemInstance *woodHoe_instance = new ItemInstance;
ALLOC_CHECK(woodHoe_instance);
woodHoe_instance->count = 255;
woodHoe_instance->auxiliary = 0;
woodHoe_instance->id = 290;
filling_container->addItem(woodHoe_instance);
(*FillingContainer_addItem)(filling_container, woodHoe_instance);
ItemInstance *stoneHoe_instance = new ItemInstance;
ALLOC_CHECK(stoneHoe_instance);
stoneHoe_instance->count = 255;
stoneHoe_instance->auxiliary = 0;
stoneHoe_instance->id = 291;
filling_container->addItem(stoneHoe_instance);
(*FillingContainer_addItem)(filling_container, stoneHoe_instance);
ItemInstance *flint1_instance = new ItemInstance;
ALLOC_CHECK(flint1_instance);
flint1_instance->count = 255;
flint1_instance->auxiliary = 0;
flint1_instance->id = 292;
filling_container->addItem(flint1_instance);
(*FillingContainer_addItem)(filling_container, flint1_instance);
ItemInstance *diamondHoe_instance = new ItemInstance;
ALLOC_CHECK(diamondHoe_instance);
diamondHoe_instance->count = 255;
diamondHoe_instance->auxiliary = 0;
diamondHoe_instance->id = 293;
filling_container->addItem(diamondHoe_instance);
(*FillingContainer_addItem)(filling_container, diamondHoe_instance);
ItemInstance *goldHoe_instance = new ItemInstance;
ALLOC_CHECK(goldHoe_instance);
goldHoe_instance->count = 255;
goldHoe_instance->auxiliary = 0;
goldHoe_instance->id = 294;
filling_container->addItem(goldHoe_instance);
(*FillingContainer_addItem)(filling_container, goldHoe_instance);
ItemInstance *seeds_instance = new ItemInstance;
ALLOC_CHECK(seeds_instance);
seeds_instance->count = 255;
seeds_instance->auxiliary = 0;
seeds_instance->id = 295;
filling_container->addItem(seeds_instance);
(*FillingContainer_addItem)(filling_container, seeds_instance);
ItemInstance *wheat_instance = new ItemInstance;
ALLOC_CHECK(wheat_instance);
wheat_instance->count = 255;
wheat_instance->auxiliary = 0;
wheat_instance->id = 296;
filling_container->addItem(wheat_instance);
(*FillingContainer_addItem)(filling_container, wheat_instance);
ItemInstance *bread_instance = new ItemInstance;
ALLOC_CHECK(bread_instance);
bread_instance->count = 255;
bread_instance->auxiliary = 0;
bread_instance->id = 297;
filling_container->addItem(bread_instance);
ItemInstance *diamondHelm_instance = new ItemInstance;
diamondHelm_instance->count = 255;
diamondHelm_instance->auxiliary = 0;
diamondHelm_instance->id = 310;
filling_container->addItem(diamondHelm_instance);
ItemInstance *diamondChest_instance = new ItemInstance;
diamondChest_instance->count = 255;
diamondChest_instance->auxiliary = 0;
diamondChest_instance->id = 311;
filling_container->addItem(diamondChest_instance);
ItemInstance *diamondLeg_instance = new ItemInstance;
diamondLeg_instance->count = 255;
diamondLeg_instance->auxiliary = 0;
diamondLeg_instance->id = 312;
filling_container->addItem(diamondLeg_instance);
ItemInstance *diamondBoot_instance = new ItemInstance;
diamondBoot_instance->count = 255;
diamondBoot_instance->auxiliary = 0;
diamondBoot_instance->id = 313;
filling_container->addItem(diamondBoot_instance);
ItemInstance *leatherCap_instance = new ItemInstance;
leatherCap_instance->count = 255;
leatherCap_instance->auxiliary = 0;
leatherCap_instance->id = 298;
filling_container->addItem(leatherCap_instance);
ItemInstance *leatherShirt_instance = new ItemInstance;
leatherShirt_instance->count = 255;
leatherShirt_instance->auxiliary = 0;
leatherShirt_instance->id = 299;
filling_container->addItem(leatherShirt_instance);
ItemInstance *leatherPants_instance = new ItemInstance;
leatherPants_instance->count = 255;
leatherPants_instance->auxiliary = 0;
leatherPants_instance->id = 300;
filling_container->addItem(leatherPants_instance);
ItemInstance *leatherBoots_instance = new ItemInstance;
leatherBoots_instance->count = 255;
leatherBoots_instance->auxiliary = 0;
leatherBoots_instance->id = 301;
filling_container->addItem(leatherBoots_instance);
ItemInstance *chainHelm_instance = new ItemInstance;
chainHelm_instance->count = 255;
chainHelm_instance->auxiliary = 0;
chainHelm_instance->id = 302;
filling_container->addItem(chainHelm_instance);
ItemInstance *chainShirt_instance = new ItemInstance;
chainShirt_instance->count = 255;
chainShirt_instance->auxiliary = 0;
chainShirt_instance->id = 303;
filling_container->addItem(chainShirt_instance);
ItemInstance *chainLegs_instance = new ItemInstance;
chainLegs_instance->count = 255;
chainLegs_instance->auxiliary = 0;
chainLegs_instance->id = 304;
filling_container->addItem(chainLegs_instance);
ItemInstance *chainBoots_instance = new ItemInstance;
chainBoots_instance->count = 255;
chainBoots_instance->auxiliary = 0;
chainBoots_instance->id = 305;
filling_container->addItem(chainBoots_instance);
ItemInstance *goldHelm_instance = new ItemInstance;
goldHelm_instance->count = 255;
goldHelm_instance->auxiliary = 0;
goldHelm_instance->id = 314;
filling_container->addItem(goldHelm_instance);
ItemInstance *goldChest_instance = new ItemInstance;
goldChest_instance->count = 255;
goldChest_instance->auxiliary = 0;
goldChest_instance->id = 315;
filling_container->addItem(goldChest_instance);
ItemInstance *goldLegs_instance = new ItemInstance;
goldLegs_instance->count = 255;
goldLegs_instance->auxiliary = 0;
goldLegs_instance->id = 316;
filling_container->addItem(goldLegs_instance);
ItemInstance *goldBoots_instance = new ItemInstance;
goldBoots_instance->count = 255;
goldBoots_instance->auxiliary = 0;
goldBoots_instance->id = 317;
filling_container->addItem(goldBoots_instance);
ItemInstance *ironHelm_instance = new ItemInstance;
ironHelm_instance->count = 255;
ironHelm_instance->auxiliary = 0;
ironHelm_instance->id = 306;
filling_container->addItem(ironHelm_instance);
ItemInstance *ironChest_instance = new ItemInstance;
ironChest_instance->count = 255;
ironChest_instance->auxiliary = 0;
ironChest_instance->id = 307;
filling_container->addItem(ironChest_instance);
ItemInstance *ironLegs_instance = new ItemInstance;
ironLegs_instance->count = 255;
ironLegs_instance->auxiliary = 0;
ironLegs_instance->id = 308;
filling_container->addItem(ironLegs_instance);
ItemInstance *ironBoots_instance = new ItemInstance;
ironBoots_instance->count = 255;
ironBoots_instance->auxiliary = 0;
ironBoots_instance->id = 309;
filling_container->addItem(ironBoots_instance);
(*FillingContainer_addItem)(filling_container, bread_instance);
ItemInstance *flint2_instance = new ItemInstance;
ALLOC_CHECK(flint2_instance);
flint2_instance->count = 255;
flint2_instance->auxiliary = 0;
flint2_instance->id = 318;
filling_container->addItem(flint2_instance);
(*FillingContainer_addItem)(filling_container, flint2_instance);
ItemInstance *porkRaw_instance = new ItemInstance;
ALLOC_CHECK(porkRaw_instance);
porkRaw_instance->count = 255;
porkRaw_instance->auxiliary = 0;
porkRaw_instance->id = 319;
filling_container->addItem(porkRaw_instance);
(*FillingContainer_addItem)(filling_container, porkRaw_instance);
ItemInstance *leather_instance = new ItemInstance;
ALLOC_CHECK(leather_instance);
leather_instance->count = 255;
leather_instance->auxiliary = 0;
leather_instance->id = 334;
filling_container->addItem(leather_instance);
(*FillingContainer_addItem)(filling_container, leather_instance);
ItemInstance *clayBrick_instance = new ItemInstance;
ALLOC_CHECK(clayBrick_instance);
clayBrick_instance->count = 255;
clayBrick_instance->auxiliary = 0;
clayBrick_instance->id = 336;
filling_container->addItem(clayBrick_instance);
(*FillingContainer_addItem)(filling_container, clayBrick_instance);
ItemInstance *clay_instance = new ItemInstance;
ALLOC_CHECK(clay_instance);
clay_instance->count = 255;
clay_instance->auxiliary = 0;
clay_instance->id = 337;
filling_container->addItem(clay_instance);
(*FillingContainer_addItem)(filling_container, clay_instance);
ItemInstance *notepad_instance = new ItemInstance;
ALLOC_CHECK(notepad_instance);
notepad_instance->count = 255;
notepad_instance->auxiliary = 0;
notepad_instance->id = 339;
filling_container->addItem(notepad_instance);
(*FillingContainer_addItem)(filling_container, notepad_instance);
ItemInstance *book_instance = new ItemInstance;
ALLOC_CHECK(book_instance);
book_instance->count = 255;
book_instance->auxiliary = 0;
book_instance->id = 340;
filling_container->addItem(book_instance);
(*FillingContainer_addItem)(filling_container, book_instance);
ItemInstance *slimeball_instance = new ItemInstance;
ALLOC_CHECK(slimeball_instance);
slimeball_instance->count = 255;
slimeball_instance->auxiliary = 0;
slimeball_instance->id = 341;
filling_container->addItem(slimeball_instance);
(*FillingContainer_addItem)(filling_container, slimeball_instance);
ItemInstance *compass_instance = new ItemInstance;
ALLOC_CHECK(compass_instance);
compass_instance->count = 255;
compass_instance->auxiliary = 0;
compass_instance->id = 345;
filling_container->addItem(compass_instance);
(*FillingContainer_addItem)(filling_container, compass_instance);
ItemInstance *clock_instance = new ItemInstance;
ALLOC_CHECK(clock_instance);
clock_instance->count = 255;
clock_instance->auxiliary = 0;
clock_instance->id = 347;
filling_container->addItem(clock_instance);
(*FillingContainer_addItem)(filling_container, clock_instance);
ItemInstance *glowDust_instance = new ItemInstance;
ALLOC_CHECK(glowDust_instance);
glowDust_instance->count = 255;
glowDust_instance->auxiliary = 0;
glowDust_instance->id = 348;
filling_container->addItem(glowDust_instance);
(*FillingContainer_addItem)(filling_container, glowDust_instance);
ItemInstance *bone_instance = new ItemInstance;
ALLOC_CHECK(bone_instance);
bone_instance->count = 255;
bone_instance->auxiliary = 0;
bone_instance->id = 352;
filling_container->addItem(bone_instance);
(*FillingContainer_addItem)(filling_container, bone_instance);
ItemInstance *sugar_instance = new ItemInstance;
ALLOC_CHECK(sugar_instance);
sugar_instance->count = 255;
sugar_instance->auxiliary = 0;
sugar_instance->id = 353;
filling_container->addItem(sugar_instance);
(*FillingContainer_addItem)(filling_container, sugar_instance);
ItemInstance *melon_instance = new ItemInstance;
ALLOC_CHECK(melon_instance);
melon_instance->count = 255;
melon_instance->auxiliary = 0;
melon_instance->id = 360;
filling_container->addItem(melon_instance);
(*FillingContainer_addItem)(filling_container, melon_instance);
ItemInstance *beefRaw_instance = new ItemInstance;
ALLOC_CHECK(beefRaw_instance);
beefRaw_instance->count = 255;
beefRaw_instance->auxiliary = 0;
beefRaw_instance->id = 363;
filling_container->addItem(beefRaw_instance);
(*FillingContainer_addItem)(filling_container, beefRaw_instance);
ItemInstance *chickenRaw_instance = new ItemInstance;
ALLOC_CHECK(chickenRaw_instance);
chickenRaw_instance->count = 255;
chickenRaw_instance->auxiliary = 0;
chickenRaw_instance->id = 365;
filling_container->addItem(chickenRaw_instance);
(*FillingContainer_addItem)(filling_container, chickenRaw_instance);
}
// Init

View File

@ -3,15 +3,13 @@ cmake_minimum_required(VERSION 3.16.0)
# Build For ARM
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_PROCESSOR "arm")
# Start Project
project(recipes)
# Include SDK
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn/sdk/sdk.cmake")
include("$ENV{HOME}/.minecraft-pi/sdk/lib/minecraft-pi-reborn-legacy-client/sdk/sdk.cmake")
# Build
add_library(recipes SHARED recipes.cpp)
target_link_libraries(recipes mods reborn-util symbols)
target_link_libraries(recipes mods-headers reborn-util symbols misc)

View File

@ -1,19 +1,18 @@
#include <libreborn/patch.h>
// Headers
#include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#include <mods/misc/misc.h>
// Custom Crafting Recipes
#define SAND 12
static void Recipes_injection(Recipes *recipes) {
static void Recipes_injection(unsigned char *recipes) {
// Add
Recipes_Type type1 = {
.item = 0,
.tile = 0,
.instance = {
.count = 1,
.id = SAND,
.id = 12,
.auxiliary = 0
},
.letter = 'a'
@ -33,19 +32,13 @@ static void Recipes_injection(Recipes *recipes) {
.id = 344,
.auxiliary = 0
};
std::vector<Recipes_Type> types = {type1, type2};
recipes->addShapelessRecipe(result, types);
(*Recipes_addShapelessRecipe)(recipes, result, {type1, type2});
}
// Custom Furnace Recipes
static void FurnaceRecipes_injection(FurnaceRecipes *recipes) {
static void FurnaceRecipes_injection(unsigned char *recipes) {
// Add
ItemInstance result = {
.count = 1,
.id = 246,
.auxiliary = 0
};
recipes->addFurnaceRecipe(49, result);
(*FurnaceRecipes_addFurnaceRecipe)(recipes, 49, {.count = 1, .id = 246, .auxiliary = 0});
}
// Init
@ -56,10 +49,4 @@ __attribute__((constructor)) static void init_recipes() {
// Setup
misc_run_on_recipes_setup(Recipes_injection);
misc_run_on_furnace_recipes_setup(FurnaceRecipes_injection);
// Recipe Remainder
overwrite_calls(Minecraft_init, [](Minecraft_init_t original, Minecraft *self) {
original(self);
Item::items[SAND]->craftingRemainingItem = Item::snowball;
});
}

View File

@ -1,38 +1,23 @@
project(images)
# Logo
install(
FILES "modern_logo.png"
DESTINATION "${MCPI_INSTALL_DIR}/data/images/gui"
)
# Title Background
if(NOT MCPI_HEADLESS_MODE)
install(
FILES "background.png"
DESTINATION "${MCPI_INSTALL_DIR}/data/images/gui"
RENAME "titleBG.png"
)
# Mojang Textures
install(
FILES "mojang/chest.png"
DESTINATION "${MCPI_INSTALL_DIR}/data/images/item"
)
install(
FILES "mojang/shadow.png" "mojang/vignette.png" "mojang/grasscolor.png"
DESTINATION "${MCPI_INSTALL_DIR}/data/images/misc"
)
endif()
# Icon
set(ICON_DIR "${MCPI_SHARE_DIR}/icons/hicolor/512x512/apps")
install(
FILES "icon.png"
DESTINATION "${ICON_DIR}"
DESTINATION "${MCPI_SHARE_DIR}/icons/hicolor/scalable/apps"
RENAME "${MCPI_APP_ID}.png"
)
# AppImage
if(MCPI_IS_APPIMAGE_BUILD)
install_symlink("${ICON_DIR}/${MCPI_APP_ID}.png" "${MCPI_APP_ID}.png")
install_symlink("${MCPI_SHARE_DIR}/icons/hicolor/scalable/apps/${MCPI_APP_ID}.png" "${MCPI_APP_ID}.png")
install_symlink("${MCPI_APP_ID}.png" ".DirIcon")
endif()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

After

Width:  |  Height:  |  Size: 155 KiB

View File

@ -1,42 +1,20 @@
project(launcher)
# Launcher
add_executable(launcher
src/bootstrap/bootstrap.cpp
src/bootstrap/mods.cpp
src/bootstrap/assets.cpp
src/bootstrap/patchelf.cpp
src/bootstrap/debug.cpp
src/util/util.cpp
src/util/sdk.cpp
src/util/env.cpp
src/logger/logger.cpp
src/logger/crash-report.cpp
src/options/parser.cpp
src/main.cpp
src/ui/frame.cpp
src/ui/color.cpp
src/client/configuration.cpp
src/client/cache.cpp
src/client/ui.cpp
src/updater/updater.cpp
)
target_link_libraries(launcher
reborn-util
LIB_LIEF
imgui
trampoline-headers
pthread
)
add_executable(launcher src/bootstrap.c src/patchelf.cpp src/crash-report.c)
if(MCPI_SERVER_MODE)
target_sources(launcher PRIVATE src/server/launcher.c)
else()
embed_resource(launcher src/client/available-feature-flags)
target_sources(launcher PRIVATE src/client/launcher.cpp src/client/cache.cpp)
endif()
target_link_libraries(launcher reborn-util LIB_LIEF)
# RPath
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
target_link_options(launcher PRIVATE "LINKER:--disable-new-dtags")
# Files
target_compile_definitions(launcher PRIVATE _FILE_OFFSET_BITS=64)
# Install
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")
install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_APP_NAME}")
install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_VARIANT_NAME}")
# Install Desktop Entry
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
@ -44,13 +22,22 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
"Name=${MCPI_APP_TITLE}\n"
"Comment=Fun with Blocks\n"
"Icon=${MCPI_APP_ID}\n"
"Exec=${MCPI_APP_NAME}\n"
"Exec=${MCPI_VARIANT_NAME}\n"
"Type=Application\n"
"Categories=Game;\n"
)
if(MCPI_HEADLESS_MODE)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
"Terminal=true\n"
"NoDisplay=true\n"
)
else()
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
"Terminal=false\n"
"StartupNotify=false\n"
"StartupWMClass=${MCPI_APP_ID}\n"
)
endif()
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
DESTINATION "${MCPI_SHARE_DIR}/applications"
@ -69,13 +56,13 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
" <p>Minecraft: Pi Edition Modding Project.</p>\n"
" <p>NOTE: This is not verified by, affiliated with, or supported by Mojang or Microsoft.</p>\n"
" </description>\n"
" <url type=\"homepage\">${MCPI_REPO}</url>\n"
" <url type=\"homepage\">https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn</url>\n"
" <launchable type=\"desktop-id\">${MCPI_APP_ID}.desktop</launchable>\n"
" <provides>\n"
" <id>${MCPI_APP_ID}.desktop</id>\n"
" <id>com.thebrokenrail.MCPIRebornClient.desktop</id>\n"
" </provides>\n"
" <project_license>LicenseRef-proprietary</project_license>\n"
" <developer_name>${MCPI_AUTHOR} &amp; Mojang AB</developer_name>\n"
" <developer_name>TheBrokenRail &amp; Mojang AB</developer_name>\n"
" <content_rating type=\"oars-1.0\">\n"
" <content_attribute id=\"violence-cartoon\">moderate</content_attribute>\n"
" <content_attribute id=\"violence-fantasy\">none</content_attribute>\n"
@ -101,11 +88,17 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
" <releases>\n"
" <release version=\"${MCPI_VERSION}\" date=\"${MCPI_VERSION_DATE}\"></release>\n"
" </releases>\n"
)
if(NOT MCPI_HEADLESS_MODE)
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
" <screenshots>\n"
" <screenshot type=\"default\">\n"
" <image>${MCPI_REPO}/raw/branch/master/images/start.png</image>\n"
" <image>https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn/raw/branch/master/images/start.png</image>\n"
" </screenshot>\n"
" </screenshots>\n"
)
endif()
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
"</component>\n"
)
install(
@ -116,8 +109,6 @@ install(
# AppImage
if(MCPI_IS_APPIMAGE_BUILD)
install_symlink("bin/${MCPI_APP_NAME}" "AppRun")
install_symlink("bin/${MCPI_VARIANT_NAME}" "AppRun")
install_symlink("${MCPI_SHARE_DIR}/applications/${MCPI_APP_ID}.desktop" "${MCPI_APP_ID}.desktop")
# Updater
target_sources(launcher PRIVATE src/updater/appimage.cpp)
endif()

485
launcher/src/bootstrap.c Normal file
View File

@ -0,0 +1,485 @@
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <libreborn/libreborn.h>
#include "bootstrap.h"
#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"
// Exit Handler
static void exit_handler(__attribute__((unused)) int signal_id) {
// Pass Signal To Child
murder_children();
while (wait(NULL) > 0) {}
_exit(EXIT_SUCCESS);
}
// Pre-Bootstrap
void pre_bootstrap(int argc, char *argv[]) {
// Set Debug Tag
reborn_debug_tag = "(Launcher) ";
// Disable stdout Buffering
setvbuf(stdout, NULL, _IONBF, 0);
// Print Version
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0) {
// Print
printf("Reborn Legacy v%s\n", MCPI_VERSION);
fflush(stdout);
exit(EXIT_SUCCESS);
}
}
// Setup Logging
setup_log_file();
// --debug
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--debug") == 0) {
set_and_print_env("MCPI_DEBUG", "1");
break;
}
}
// Set Default Native Component Environment
#define set_variable_default(name) set_and_print_env("MCPI_NATIVE_" name, getenv(name));
for_each_special_environmental_variable(set_variable_default);
// GTK Dark Mode
#ifndef MCPI_SERVER_MODE
set_and_print_env("GTK_THEME", "Adwaita:dark");
#endif
// Get Binary Directory
char *binary_directory = get_binary_directory();
// Configure PATH
{
// Add Library Directory
char *new_path = NULL;
safe_asprintf(&new_path, "%s/bin", binary_directory);
// Add Existing PATH
{
char *value = getenv("PATH");
if (value != NULL && strlen(value) > 0) {
string_append(&new_path, ":%s", value);
}
}
// Set And Free
set_and_print_env("PATH", new_path);
free(new_path);
}
// Free Binary Directory
free(binary_directory);
// Setup Crash Reports
setup_crash_report();
// AppImage
#ifdef MCPI_IS_APPIMAGE_BUILD
{
char *owd = getenv("OWD");
if (owd != NULL && chdir(owd) != 0) {
ERR("AppImage: Unable To Fix Current Directory: %s", strerror(errno));
}
}
#endif
// Install Signal Handlers
struct sigaction act_sigint;
memset((void *) &act_sigint, 0, sizeof (struct sigaction));
act_sigint.sa_flags = SA_RESTART;
act_sigint.sa_handler = &exit_handler;
sigaction(SIGINT, &act_sigint, NULL);
struct sigaction act_sigterm;
memset((void *) &act_sigterm, 0, sizeof (struct sigaction));
act_sigterm.sa_flags = SA_RESTART;
act_sigterm.sa_handler = &exit_handler;
sigaction(SIGTERM, &act_sigterm, NULL);
}
// Copy SDK Into ~/.minecraft-pi
void run_simple_command(const char *const command[], const char *error) {
int status = 0;
char *output = run_command(command, &status);
if (output != NULL) {
free(output);
}
if (!is_exit_status_success(status)) {
ERR("%s", error);
}
}
#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...");
// Get Binary Directory
char *binary_directory = get_binary_directory();
// Copy SDK
copy_sdk(binary_directory);
// Set MCPI_REBORN_ASSETS_PATH
{
char *assets_path = realpath("/proc/self/exe", NULL);
ALLOC_CHECK(assets_path);
chop_last_component(&assets_path);
string_append(&assets_path, "/data");
set_and_print_env("MCPI_REBORN_ASSETS_PATH", assets_path);
free(assets_path);
}
// Resolve Binary Path & Set MCPI_DIRECTORY
char *resolved_path = NULL;
{
// Log
DEBUG("Resolving File Paths...");
// Resolve Full Binary Path
char *full_path = NULL;
safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory);
resolved_path = realpath(full_path, NULL);
ALLOC_CHECK(resolved_path);
free(full_path);
}
// Fix MCPI Dependencies
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
{
// Log
DEBUG("Patching ELF Dependencies...");
// Find Linker
char *linker = NULL;
// Select Linker
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
// Use ARM Sysroot Linker
safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory);
#else
// Use Current Linker
linker = patch_get_interpreter();
#endif
// Patch
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker);
// Free Linker Path
if (linker != NULL) {
free(linker);
}
// Verify
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
IMPOSSIBLE();
}
}
// Set MCPI_VANILLA_ASSETS_PATH
{
char *assets_path = strdup(resolved_path);
ALLOC_CHECK(assets_path);
chop_last_component(&assets_path);
string_append(&assets_path, "/data");
set_and_print_env("MCPI_VANILLA_ASSETS_PATH", assets_path);
free(assets_path);
}
// Free Resolved Path
free(resolved_path);
// Configure Library Search Path
{
// Log
DEBUG("Setting Linker Search Paths...");
// Prepare
char *transitive_ld_path = NULL;
char *mcpi_ld_path = NULL;
// Library Search Path For Native Components
{
// Add Native Library Directory
safe_asprintf(&transitive_ld_path, "%s/lib/native", binary_directory);
// Add Host LD_LIBRARY_PATH
{
char *value = getenv("LD_LIBRARY_PATH");
if (value != NULL && strlen(value) > 0) {
string_append(&transitive_ld_path, ":%s", value);
}
}
// Set
set_and_print_env("MCPI_NATIVE_LD_LIBRARY_PATH", transitive_ld_path);
free(transitive_ld_path);
}
// Library Search Path For ARM Components
{
// Add ARM Library Directory
safe_asprintf(&mcpi_ld_path, "%s/lib/arm", binary_directory);
// Add ARM Sysroot Libraries (Ensure Priority) (Ignore On Actual ARM System)
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
string_append(&mcpi_ld_path, ":%s/sysroot/lib:%s/sysroot/lib/arm-linux-gnueabihf:%s/sysroot/usr/lib:%s/sysroot/usr/lib/arm-linux-gnueabihf", binary_directory, binary_directory, binary_directory, binary_directory);
#endif
// Add Host LD_LIBRARY_PATH
{
char *value = getenv("LD_LIBRARY_PATH");
if (value != NULL && strlen(value) > 0) {
string_append(&mcpi_ld_path, ":%s", value);
}
}
// Set
set_and_print_env("MCPI_ARM_LD_LIBRARY_PATH", mcpi_ld_path);
free(mcpi_ld_path);
}
// Setup iconv
{
// Native Components
char *host_gconv_path = getenv("GCONV_PATH");
set_and_print_env("MCPI_NATIVE_GCONV_PATH", host_gconv_path);
// ARM Components
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
char *gconv_path = NULL;
safe_asprintf(&gconv_path, "%s/sysroot/usr/lib/gconv", binary_directory);
set_and_print_env("MCPI_ARM_GCONV_PATH", gconv_path);
free(gconv_path);
#else
set_and_print_env("MCPI_ARM_GCONV_PATH", host_gconv_path);
#endif
}
}
// Configure Preloaded Objects
{
// Log
DEBUG("Locating Mods...");
// Native Components
char *host_ld_preload = getenv("LD_PRELOAD");
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 "/legacy-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);
}
}
// Free Binary Directory
free(binary_directory);
// Start Game
INFO("Starting Game...");
// Arguments
int argv_start = 1; // argv = &new_args[argv_start]
const char *new_args[argv_start /* 1 Potential Prefix Argument (QEMU) */ + argc + 1 /* NULL-Terminator */]; //
// Copy Existing Arguments
for (int i = 1; i < argc; i++) {
new_args[i + argv_start] = argv[i];
}
// NULL-Terminator
new_args[argv_start + argc] = NULL;
// Set Executable Argument
new_args[argv_start] = new_mcpi_exe_path;
// Non-ARM Systems Need QEMU
#ifndef __ARM_ARCH
argv_start--;
new_args[argv_start] = QEMU_BINARY;
#endif
// Setup Environment
setup_exec_environment(1);
// Pass LD_* Variables Through QEMU
#ifndef __ARM_ARCH
char *qemu_set_env = NULL;
#define pass_variable_through_qemu(name) string_append(&qemu_set_env, "%s%s=%s", qemu_set_env == NULL ? "" : ",", name, getenv(name));
for_each_special_environmental_variable(pass_variable_through_qemu);
set_and_print_env("QEMU_SET_ENV", qemu_set_env);
free(qemu_set_env);
// Treat QEMU Itself As A Native Component
setup_exec_environment(0);
#endif
// Run
const char **new_argv = &new_args[argv_start];
safe_execvpe(new_argv, (const char *const *) environ);
}

14
launcher/src/bootstrap.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void run_simple_command(const char *const command[], const char *error);
void pre_bootstrap(int argc, char *argv[]);
void bootstrap(int argc, char *argv[]);
#ifdef __cplusplus
}
#endif

View File

@ -1,15 +0,0 @@
#include <libreborn/env/env.h>
#include "bootstrap.h"
#include "../util/util.h"
// Setup Asset Paths
static void setup_path(const char *env_name, std::string assets_path) {
chop_last_component(assets_path);
assets_path += "/data";
set_and_print_env(env_name, assets_path.c_str());
}
void bootstrap_assets(const std::string &original_game_binary) {
setup_path(_MCPI_REBORN_ASSETS_PATH_ENV, safe_realpath("/proc/self/exe"));
setup_path(_MCPI_VANILLA_ASSETS_PATH_ENV, original_game_binary);
}

View File

@ -1,78 +0,0 @@
#include <string>
#include <vector>
#include <libreborn/log.h>
#include <libreborn/env/env.h>
#include <libreborn/config.h>
#include <libreborn/util/exec.h>
#include "../util/util.h"
#include "bootstrap.h"
#define MCPI_BINARY "minecraft-pi"
#define REQUIRED_PAGE_SIZE 4096
// Bootstrap
void bootstrap(const options_t &options) {
// Debug Information
print_debug_information();
// Check Page Size
const long page_size = sysconf(_SC_PAGESIZE);
if (page_size != REQUIRED_PAGE_SIZE) {
CONDITIONAL_ERR(!options.skip_pagesize_check, "Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
}
// Get Binary Directory
const std::string binary_directory = get_binary_directory();
DEBUG("Binary Directory: %s", binary_directory.c_str());
// Copy SDK
if (!reborn_is_server()) {
copy_sdk(binary_directory, false);
}
// Resolve Binary Path
DEBUG("Resolving File Paths...");
std::string original_game_binary = binary_directory + ("/" MCPI_BINARY);
original_game_binary = safe_realpath(original_game_binary);
const char *custom_binary = getenv(MCPI_BINARY_ENV);
const std::string game_binary = custom_binary ? safe_realpath(custom_binary) : original_game_binary;
// Configure Preloaded Objects
DEBUG("Locating Mods...");
const std::vector<std::string> mcpi_ld_preload = bootstrap_mods(binary_directory);
// Configure Library Search Path
DEBUG("Setting Linker Search Paths...");
const std::vector<std::string> mcpi_ld_path = get_ld_path(binary_directory);
// Assets
DEBUG("Finding Assets...");
bootstrap_assets(original_game_binary);
// Patch Binary
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
DEBUG("Patching ELF...");
patch_mcpi_elf_dependencies(game_binary, new_mcpi_exe_path, get_new_linker(binary_directory), mcpi_ld_path, mcpi_ld_preload);
// Start Game
INFO("Starting Game...");
// Arguments
const std::vector<std::string> args {
#ifdef MCPI_BUILD_RUNTIME
"runtime",
#endif
new_mcpi_exe_path
};
// Run
const char *new_argv[args.size() + 1];
for (std::vector<std::string>::size_type i = 0; i < args.size(); i++) {
new_argv[i] = args[i].c_str();
}
new_argv[args.size()] = nullptr;
safe_execvpe(new_argv, environ);
}

View File

@ -1,20 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include "../options/parser.h"
#define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched"
void bootstrap(const options_t &options);
// Debugging
void print_debug_information();
// Mods
std::vector<std::string> bootstrap_mods(const std::string &binary_directory);
// Assets
void bootstrap_assets(const std::string &original_game_binary);
// ELF
std::string get_new_linker(const std::string &binary_directory);
std::vector<std::string> get_ld_path(const std::string &binary_directory);
void patch_mcpi_elf_dependencies(const std::string &original_path, char *new_path, const std::string &interpreter, const std::vector<std::string> &rpath, const std::vector<std::string> &mods);

View File

@ -1,38 +0,0 @@
#include <libreborn/log.h>
#include <libreborn/util/exec.h>
#include <libreborn/config.h>
#include "bootstrap.h"
// Debug Information
static void run_debug_command(const char *const command[], const char *prefix) {
int status = 0;
const std::vector<unsigned char> *output = run_command(command, &status);
if (!is_exit_status_success(status)) {
ERR("Unable To Gather Debug Information");
}
std::string output_str = (const char *) output->data();
delete output;
// Trim
const std::string::size_type length = output_str.length();
if (length > 0 && output_str[length - 1] == '\n') {
output_str.pop_back();
}
// Print
DEBUG("%s: %s", prefix, output_str.c_str());
}
void print_debug_information() {
// System Information
constexpr const char *const command[] = {"uname", "-a", nullptr};
run_debug_command(command, "System Information");
// Version
DEBUG("Reborn Version: v%s", MCPI_VERSION);
// Architecture
std::string arch = MCPI_ARCH;
for (char &c : arch) {
c = char(std::toupper(c));
}
DEBUG("Reborn Target Architecture: %s", arch.c_str());
}

View File

@ -1,74 +0,0 @@
#include <dirent.h>
#include <cerrno>
#include <sys/stat.h>
#include <unistd.h>
#include <cstring>
#include <libreborn/log.h>
#include <libreborn/util/util.h>
#include "bootstrap.h"
#include "../util/util.h"
// Get All Mods In Folder
static void load(std::vector<std::string> &ld_preload, const std::string &folder, int recursion_limit = 128);
static void handle_file(std::vector<std::string> &ld_preload, const std::string &file, const int recursion_limit) {
// Check Type
struct stat file_stat = {};
lstat(file.c_str(), &file_stat);
if (S_ISDIR(file_stat.st_mode)) {
// Recurse Into Directory
load(ld_preload, std::string(file) + '/', recursion_limit - 1);
} else if (S_ISLNK(file_stat.st_mode)) {
// Resolve Symlink
const std::string resolved_file = safe_realpath(file);
handle_file(ld_preload, resolved_file, recursion_limit);
} else if (S_ISREG(file_stat.st_mode)) {
// Check If File Is Accessible
const int result = access(file.c_str(), R_OK);
if (result == 0) {
// Add To LD_PRELOAD
DEBUG("Found Mod: %s", file.c_str());
ld_preload.push_back(file);
} else if (result == -1 && errno != 0) {
// Fail
WARN("Unable To Access: %s: %s", file.c_str(), strerror(errno));
errno = 0;
}
}
}
static void load(std::vector<std::string> &ld_preload, const std::string &folder, const int recursion_limit) {
// Check Recursion
if (recursion_limit <= 0) {
ERR("Reached Recursion Limit While Loading Mods");
}
// Make Directory
ensure_directory(folder.c_str());
// Read
read_directory(folder, [&folder, &ld_preload, &recursion_limit](const dirent *entry) {
// Get Full Name
const std::string name = folder + entry->d_name;
// Handle
handle_file(ld_preload, name, recursion_limit);
});
}
// Bootstrap Mods
#define SUBDIRECTORY_FOR_MODS "/mods/"
std::vector<std::string> bootstrap_mods(const std::string &binary_directory) {
// Prepare
std::vector<std::string> preload;
// Load
const std::vector folders = {
home_get(),
binary_directory
};
for (std::string mods_folder : folders) {
mods_folder += SUBDIRECTORY_FOR_MODS;
load(preload, mods_folder);
}
// Return
return preload;
}

View File

@ -1,125 +0,0 @@
#include <cstdlib>
#include <sys/stat.h>
#include <ranges>
#include <LIEF/ELF.hpp>
#include <libreborn/util/util.h>
#include <libreborn/config.h>
#include "bootstrap.h"
// Duplicate MCPI Executable Into /tmp
static void duplicate_mcpi_executable(char *new_path) {
// Ensure Temporary Directory
ensure_directory(MCPI_PATCHED_DIR);
// Generate New File
const int new_file_fd = mkstemp(new_path);
if (new_file_fd == -1) {
ERR("Unable To Create Temporary File: %s", strerror(errno));
}
close(new_file_fd);
}
// Fix MCPI Dependencies
static std::vector<std::string> needed_libraries = {
"libmedia-layer-core.so",
"libpng12.so.0",
"libstdc++.so.6",
"libm.so.6",
"libgcc_s.so.1",
"libc.so.6",
"libpthread.so.0"
};
static std::vector<std::string> function_prefixes_to_patch = {
"SDL_",
"gl"
};
void patch_mcpi_elf_dependencies(const std::string &original_path, char *new_path, const std::string &interpreter, const std::vector<std::string> &rpath, const std::vector<std::string> &mods) {
// Duplicate MCPI executable into /tmp so it can be modified.
duplicate_mcpi_executable(new_path);
// Load Binary
const std::unique_ptr<LIEF::ELF::Binary> binary = LIEF::ELF::Parser::parse(original_path);
// Set Interpreter
binary->interpreter(interpreter);
// Remove Existing Needed Libraries
std::vector<std::string> to_remove;
for (const LIEF::ELF::DynamicEntry &entry : binary->dynamic_entries()) {
const LIEF::ELF::DynamicEntryLibrary *library = dynamic_cast<const LIEF::ELF::DynamicEntryLibrary *>(&entry);
if (library) {
to_remove.push_back(library->name());
}
}
for (const std::string &library : to_remove) {
binary->remove_library(library);
}
// Setup RPath
binary->add(LIEF::ELF::DynamicEntryRpath(rpath));
// Add Libraries
std::vector<std::string> all_libraries;
for (const std::vector<std::string> &list : {mods, needed_libraries}) {
all_libraries.insert(all_libraries.end(), list.begin(), list.end());
}
for (const std::string &library : all_libraries | std::views::reverse) {
binary->add_library(library);
}
// Fix Symbol Names
for (LIEF::ELF::Symbol &symbol : binary->dynamic_symbols()) {
if (symbol.is_function()) {
for (const std::string &prefix : function_prefixes_to_patch) {
if (symbol.name().rfind(prefix, 0) == 0) {
symbol.name("media_" + symbol.name());
break;
}
}
}
}
// Write Binary
LIEF::ELF::Builder builder{*binary};
builder.build();
builder.write(new_path);
// Fix Permissions
if (chmod(new_path, S_IRUSR | S_IXUSR) != 0) {
ERR("Unable To Set File Permissions: %s: %s", new_path, strerror(errno));
}
}
// Linker
std::string get_new_linker(const std::string &binary_directory) {
std::string linker = "/lib/ld-linux-armhf.so.3";
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
linker = binary_directory + "/sysroot" + linker;
#else
(void) binary_directory;
#endif
return linker;
}
std::vector<std::string> get_ld_path(const std::string &binary_directory) {
std::vector<std::string> mcpi_ld_path = {
// ARM Sysroot
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
"sysroot/lib",
"sysroot/lib/arm-linux-gnueabihf",
"sysroot/usr/lib",
"sysroot/usr/lib/arm-linux-gnueabihf",
#endif
// Libraries
"lib/arm"
};
// Fix Paths
for (std::string &path : mcpi_ld_path) {
path.insert(0, 1, '/');
path.insert(0, binary_directory);
}
// Return
return mcpi_ld_path;
}

View File

@ -0,0 +1,49 @@
FALSE Full Touch GUI
TRUE Fix Attacking
FALSE Force Mob Spawning
TRUE Fancy Graphics
TRUE Disable Autojump By Default
TRUE Display Nametags By Default
TRUE Show Block Outlines
FALSE Expand Creative Mode Inventory
FALSE Remove Creative Mode Restrictions
FALSE Peaceful Mode
TRUE Animated Water
TRUE Remove Invalid Item Background
TRUE Disable "gui_blocks" Atlas
TRUE Smooth Lighting
FALSE 3D Anaglyph
TRUE Fix Camera Rendering
TRUE Implement Chat
FALSE Hide Chat Messages
TRUE Implement Death Messages
TRUE Implement Game-Mode Switching
TRUE Allow Joining Survival Mode Servers
TRUE Miscellaneous Input Fixes
TRUE Bind "Q" Key To Item Dropping
TRUE Bind Common Toggleable Options To Function Keys
TRUE Render Selected Item Text
TRUE External Server Support
TRUE Load Language Files
TRUE Implement Sound Engine
TRUE Close Current Screen On Death
FALSE Disable Raw Mouse Motion (Not Recommended)
TRUE Fix Furnace Not Checking Item Auxiliary
FALSE Disable Hosting LAN Worlds
TRUE Improved Cursor Rendering
TRUE Disable V-Sync
TRUE Force Touch GUI Inventory
TRUE Fix Pause Menu
TRUE Add Title Screen Background
TRUE Force Touch GUI Button Behavior
TRUE Improved Button Hover Behavior
TRUE Implement Create World Dialog
FALSE Remove Forced GUI Lag (Can Break Joining Servers)
TRUE Add Buckets
TRUE Classic HUD
TRUE Translucent Toolbar
FALSE Force EGL
TRUE Improved Classic Title Screen
TRUE Improved Touch Title Screen
FALSE Disable Speed Bridging
FALSE Disable Creative Mode Mining Delay

View File

@ -3,105 +3,87 @@
#include <fstream>
#include <unordered_map>
#include <sstream>
#include <sys/stat.h>
#include <unistd.h>
#include <libreborn/log.h>
#include <libreborn/util/util.h>
#include <libreborn/util/io.h>
#include <libreborn/libreborn.h>
#include "launcher.h"
#include "cache.h"
#include "configuration.h"
// Get Cache Path
static std::string get_cache_path() {
return home_get() + "/.launcher-cache";
const char *home = getenv("HOME");
if (home == NULL) {
IMPOSSIBLE();
}
return std::string(home) + HOME_SUBDIRECTORY_FOR_GAME_DATA "/.launcher-cache";
}
// Load
template <typename T>
static T simple_read(std::ifstream &stream) {
T out;
stream.read((char *) &out, sizeof(T));
return out;
}
template <>
std::string simple_read<std::string>(std::ifstream &stream) {
std::string out;
if (!std::getline(stream, out, '\0')) {
out = "";
}
return out;
}
static void read_cache(std::ifstream &stream, State &ret) {
// Cache Version
const unsigned char cache_version = simple_read<unsigned char>(stream);
if (stream.eof()) {
// Unable To Read Version
WARN("Unable To Read Launcher Cache Version");
return;
}
// Support Older Versions
bool load_new_fields = true;
if (cache_version == 0) {
// Pre-v3.0.0 Cache
load_new_fields = false;
} else if (cache_version != (unsigned char) CACHE_VERSION) {
// Invalid Version
WARN("Invalid Launcher Cache Version (Expected: %i, Actual: %i)", CACHE_VERSION, (int) cache_version);
return;
}
// Load Username And Render Distance
State state;
state.username = simple_read<std::string>(stream);
state.render_distance = simple_read<std::string>(stream);
if (load_new_fields) {
state.gui_scale = simple_read<float>(stream);
state.servers.load(simple_read<std::string>(stream));
}
// Load Feature Flags
std::unordered_map<std::string, bool> flags;
while (!stream.eof()) {
std::string flag = simple_read<std::string>(stream);
flags[flag] = simple_read<bool>(stream);
stream.peek();
}
state.flags.from_cache(flags);
// Check For Error
if (!stream) {
WARN("Failure While Loading Launcher Cache");
return;
}
// Success
ret = state;
}
State load_cache() {
launcher_cache empty_cache = {
.username = DEFAULT_USERNAME,
.render_distance = DEFAULT_RENDER_DISTANCE,
.feature_flags = {}
};
launcher_cache load_cache() {
// Log
DEBUG("Loading Launcher Cache...");
// Return Value
State ret;
launcher_cache ret = empty_cache;
// Open File
std::ifstream stream(get_cache_path(), std::ios::in | std::ios::binary);
if (!stream) {
// Fail
struct stat s;
// No Warning If File Doesn't Exist
if (errno != ENOENT) {
if (stat(get_cache_path().c_str(), &s) == 0) {
WARN("Unable To Open Launcher Cache For Loading");
}
} else {
// Lock File
int lock_fd = lock_file(get_cache_path().c_str());
// Load
read_cache(stream, ret);
// Close
// Check Version
unsigned char cache_version;
stream.read((char *) &cache_version, 1);
if (stream.eof() || cache_version != (unsigned char) CACHE_VERSION) {
// Fail
if (!stream.eof()) {
WARN("Invalid Launcher Cache Version (Expected: %i, Actual: %i)", (int) CACHE_VERSION, (int) cache_version);
} else {
WARN("Unable To Read Launcher Cache Version");
}
stream.close();
} else {
// Load Username And Render Distance
launcher_cache cache;
std::getline(stream, cache.username, '\0');
std::getline(stream, cache.render_distance, '\0');
// Load Feature Flags
std::string flag;
while (!stream.eof() && std::getline(stream, flag, '\0')) {
if (flag.length() > 0) {
unsigned char is_enabled = 0;
stream.read((char *) &is_enabled, 1);
cache.feature_flags[flag] = is_enabled != (unsigned char) 0;
}
stream.peek();
}
// Finish
stream.close();
if (!stream) {
// Fail
WARN("Failure While Loading Launcher Cache");
} else {
// Success
ret = cache;
}
}
// Unlock File
unlock_file(get_cache_path().c_str(), lock_fd);
@ -112,33 +94,15 @@ State load_cache() {
}
// Save
template <typename T>
static void simple_write(std::ostream &stream, const T &val) {
stream.write((const char *) &val, sizeof(T));
#define write_env_to_stream(stream, env) \
{ \
const char *env_value = getenv(env); \
if (env == NULL) { \
IMPOSSIBLE(); \
} \
stream.write(env_value, strlen(env_value) + 1); \
}
template <>
void simple_write<std::string>(std::ostream &stream, const std::string &val) {
stream.write(val.c_str(), int(val.size()) + 1);
}
void write_cache(std::ostream &stream, const State &state) {
// Save Cache Version
constexpr unsigned char cache_version = CACHE_VERSION;
simple_write(stream, cache_version);
// Save Username And Render Distance
simple_write(stream, state.username);
simple_write(stream, state.render_distance);
simple_write(stream, state.gui_scale);
simple_write(stream, state.servers.to_string());
// Save Feature Flags
const std::unordered_map<std::string, bool> flags_cache = state.flags.to_cache();
for (const std::pair<const std::string, bool> &it : flags_cache) {
simple_write(stream, it.first);
simple_write(stream, it.second);
}
}
void save_cache(const State &state) {
void save_cache() {
// Log
DEBUG("Saving Launcher Cache...");
@ -149,14 +113,44 @@ void save_cache(const State &state) {
WARN("Unable To Open Launcher Cache For Saving");
} else {
// Lock File
const int lock_fd = lock_file(get_cache_path().c_str());
int lock_fd = lock_file(get_cache_path().c_str());
// Write
write_cache(stream, state);
// Save Cache Version
unsigned char cache_version = (unsigned char) CACHE_VERSION;
stream.write((const char *) &cache_version, 1);
// Save Username And Render Distance
write_env_to_stream(stream, "MCPI_USERNAME");
write_env_to_stream(stream, "MCPI_RENDER_DISTANCE");
// Save Feature Flags
std::unordered_map<std::string, bool> flags;
load_available_feature_flags([&flags](std::string flag) {
std::string stripped_flag = strip_feature_flag_default(flag, NULL);
flags[stripped_flag] = false;
});
{
const char *enabled_flags = getenv("MCPI_FEATURE_FLAGS");
if (enabled_flags == NULL) {
IMPOSSIBLE();
}
std::istringstream enabled_flags_stream(enabled_flags);
std::string flag;
while (std::getline(enabled_flags_stream, flag, '|')) {
if (flag.length() > 0) {
flags[flag] = true;
}
}
}
for (auto &it : flags) {
stream.write(it.first.c_str(), it.first.size() + 1);
unsigned char val = it.second ? (unsigned char) 1 : (unsigned char) 0;
stream.write((const char *) &val, 1);
}
// Finish
stream.close();
if (!stream) {
if (!stream.good()) {
WARN("Failure While Saving Launcher Cache");
}
@ -171,8 +165,7 @@ void wipe_cache() {
INFO("Wiping Launcher Cache...");
// Unlink File
const int ret = unlink(get_cache_path().c_str());
if (ret != 0 && errno != ENOENT) {
if (unlink(get_cache_path().c_str()) != 0) {
WARN("Failure While Wiping Cache: %s", strerror(errno));
}
}

View File

@ -1,17 +1,22 @@
#pragma once
#include <ostream>
#include <string>
#include <unordered_map>
// Cache Version
#define CACHE_VERSION 1
#define CACHE_VERSION 0
// Load Cache
struct State;
State load_cache();
typedef struct {
std::string username;
std::string render_distance;
std::unordered_map<std::string, bool> feature_flags;
} launcher_cache;
extern launcher_cache empty_cache;
launcher_cache load_cache();
// Save Cache
void write_cache(std::ostream &stream, const State &state);
void save_cache(const State &state);
void save_cache();
// Wipe Cache
void wipe_cache();

View File

@ -1,86 +0,0 @@
#include <sstream>
#include <libreborn/env/env.h>
#include "configuration.h"
#include "cache.h"
// State
State::State(): flags("") {
username = DEFAULT_USERNAME;
render_distance = DEFAULT_RENDER_DISTANCE;
gui_scale = AUTO_GUI_SCALE;
flags = Flags::get();
}
template <typename T>
static void update_from_env(const char *env, T &value, const bool save) {
if (save) {
set_and_print_env(env, obj_to_env_value(value).c_str());
} else {
const char *env_value = getenv(env);
if (env_value != nullptr) {
env_value_to_obj(value, env_value);
}
}
}
void State::update(const bool save) {
update_from_env(MCPI_FEATURE_FLAGS_ENV, flags, save);
update_from_env(MCPI_USERNAME_ENV, username, save);
update_from_env(MCPI_RENDER_DISTANCE_ENV, render_distance, save);
update_from_env(MCPI_GUI_SCALE_ENV, gui_scale, save);
update_from_env(MCPI_SERVER_LIST_ENV, servers, save);
}
bool State::operator==(const State &other) const {
std::ostringstream one;
write_cache(one, *this);
std::ostringstream two;
write_cache(two, other);
return one.str() == two.str();
}
// Handle Non-Launch Commands
void handle_non_launch_client_only_commands(const options_t &options) {
// Print Available Feature Flags
if (options.print_available_feature_flags) {
const Flags flags = Flags::get();
flags.print();
exit(EXIT_SUCCESS);
}
// Wipe Cache If Needed
if (options.wipe_cache) {
wipe_cache();
exit(EXIT_SUCCESS);
}
}
// Configure Client Options
void configure_client(const options_t &options) {
// Load Cache
State state;
bool save_settings = !options.no_cache;
if (save_settings) {
state = load_cache();
}
// Read From Environment
state.update(false);
// Show UI
if (!options.use_default) {
ConfigurationUI *ui = new ConfigurationUI(state, save_settings);
const int ret = ui->run();
delete ui;
if (ret <= 0) {
// Cancel Launch
exit(EXIT_SUCCESS);
}
}
// Save Cache
if (save_settings) {
save_cache(state);
}
// Update Environment
state.update(true);
}

View File

@ -1,60 +0,0 @@
#pragma once
#include <string>
#include "../options/parser.h"
#include "../ui/frame.h"
#include <libreborn/env/flags.h>
#include <libreborn/env/servers.h>
// Default Configuration
#define DEFAULT_USERNAME "StevePi"
#define DEFAULT_RENDER_DISTANCE "Short"
#define AUTO_GUI_SCALE 0
// State
struct State {
State();
// Methods
void update(bool save);
bool operator==(const State &other) const;
// Properties
std::string username;
std::string render_distance;
ServerList servers;
float gui_scale;
Flags flags;
};
// UI
struct ConfigurationUI final : Frame {
explicit ConfigurationUI(State &state_, bool &save_settings_);
int render() override;
private:
// Bottom Row
[[nodiscard]] int get_render_distance_index() const;
[[nodiscard]] int draw_bottom() const;
// General
void draw_main() const;
// Advanced
void draw_advanced() const;
static void draw_category(FlagNode &category);
// Server List
void draw_servers() const;
void draw_server_list() const;
// About
static void draw_centered_text(const std::string &str);
static void draw_links(const std::vector<std::pair<std::string, std::string>> &links);
static void draw_about();
// State
const State original_state;
State &state;
bool &save_settings;
};
// Handle Non-Launch Commands
void handle_non_launch_client_only_commands(const options_t &options);
// Configure Client Options
void configure_client(const options_t &options);

Some files were not shown because too many files have changed in this diff Show More