Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
seaniedan | 90c1aad7ee |
|
@ -1,122 +0,0 @@
|
||||||
name: 'CI'
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
tags:
|
|
||||||
- '*'
|
|
||||||
- '!flatpak'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# Build Project
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
mode:
|
|
||||||
- Client
|
|
||||||
- Server
|
|
||||||
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.sh ${{ matrix.arch }}
|
|
||||||
# Build
|
|
||||||
- name: Build
|
|
||||||
run: ./scripts/build.mjs appimage ${{ matrix.mode }} ${{ matrix.arch }}
|
|
||||||
- name: Upload Artifacts
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.mode }} (${{ matrix.arch }})
|
|
||||||
path: ./out/*.AppImage*
|
|
||||||
if-no-files-found: error
|
|
||||||
# Test Project
|
|
||||||
test:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
mode:
|
|
||||||
- Client
|
|
||||||
- Server
|
|
||||||
name: Test
|
|
||||||
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.sh
|
|
||||||
# Test
|
|
||||||
- name: Test
|
|
||||||
run: ./scripts/test.sh ${{ matrix.mode }}
|
|
||||||
# Example Mods
|
|
||||||
example-mods:
|
|
||||||
name: Build Example Mods
|
|
||||||
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.sh
|
|
||||||
- name: Install ARM Toolchain
|
|
||||||
run: apt-get install --no-install-recommends -y g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf
|
|
||||||
# Build SDK
|
|
||||||
- name: Build SDK
|
|
||||||
run: |
|
|
||||||
./scripts/build.mjs none client host
|
|
||||||
export _MCPI_SKIP_ROOT_CHECK=1
|
|
||||||
export DISPLAY=
|
|
||||||
./out/client/host/usr/bin/minecraft-pi-reborn-client --copy-sdk
|
|
||||||
# Build Example Mods
|
|
||||||
- name: Build Example Mods
|
|
||||||
run: ./example-mods/build.sh
|
|
||||||
- name: Upload Artifacts
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: Example Mods
|
|
||||||
path: ./example-mods/out/*
|
|
||||||
if-no-files-found: error
|
|
||||||
# Create Release
|
|
||||||
release:
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
needs: build
|
|
||||||
name: Release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: node:lts-bullseye
|
|
||||||
steps:
|
|
||||||
# Dependencies
|
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v4
|
|
||||||
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)"
|
|
|
@ -1,18 +1,11 @@
|
||||||
/out
|
out
|
||||||
/debian/tmp
|
debian/tmp
|
||||||
/.vscode
|
.vscode
|
||||||
/build*
|
build
|
||||||
/CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
*.autosave
|
*.autosave
|
||||||
/AppImageBuilder.yml
|
AppImageBuilder.yml
|
||||||
/appimage-builder-cache
|
appimage-builder-cache
|
||||||
/appimage-build
|
appimage-build
|
||||||
/AppDir
|
AppDir
|
||||||
/*.zsync
|
*.zsync
|
||||||
/*.AppImage
|
|
||||||
/core*
|
|
||||||
/qemu_*
|
|
||||||
/example-mods/out
|
|
||||||
/.testing-tmp
|
|
||||||
/cmake-build-*
|
|
||||||
/.idea
|
|
||||||
|
|
|
@ -1,24 +1,12 @@
|
||||||
|
[submodule "dependencies/libpng/src"]
|
||||||
|
path = dependencies/libpng/src
|
||||||
|
url = https://github.com/glennrp/libpng.git
|
||||||
|
[submodule "dependencies/zlib/src"]
|
||||||
|
path = dependencies/zlib/src
|
||||||
|
url = https://github.com/madler/zlib.git
|
||||||
[submodule "dependencies/glfw/src"]
|
[submodule "dependencies/glfw/src"]
|
||||||
path = dependencies/glfw/src
|
path = dependencies/glfw/src
|
||||||
url = https://github.com/glfw/glfw.git
|
url = https://github.com/glfw/glfw.git
|
||||||
[submodule "dependencies/zenity/src"]
|
[submodule "dependencies/zenity/src"]
|
||||||
path = dependencies/zenity/src
|
path = dependencies/zenity/src
|
||||||
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/zenity.git
|
url = https://gitea.thebrokenrail.com/TheBrokenRail/zenity.git
|
||||||
[submodule "dependencies/LIEF/src"]
|
|
||||||
path = dependencies/LIEF/src
|
|
||||||
url = https://github.com/lief-project/LIEF.git
|
|
||||||
[submodule "media-layer/core/gles/dependencies/gles-compatibility-layer"]
|
|
||||||
path = dependencies/gles-compatibility-layer/src
|
|
||||||
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/gles-compatibility-layer.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
|
|
||||||
[submodule "dependencies/symbol-processor/src"]
|
|
||||||
path = dependencies/symbol-processor/src
|
|
||||||
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/symbol-processor.git
|
|
||||||
|
|
219
CMakeLists.txt
219
CMakeLists.txt
|
@ -1,97 +1,107 @@
|
||||||
cmake_minimum_required(VERSION 3.17.0)
|
cmake_minimum_required(VERSION 3.13.0)
|
||||||
|
|
||||||
# Avoid Warning About DOWNLOAD_EXTRACT_TIMESTAMP
|
# Specify Options
|
||||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24.0)
|
option(MCPI_USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" FALSE)
|
||||||
cmake_policy(SET CMP0135 NEW)
|
option(MCPI_SERVER_MODE "Server Mode" FALSE)
|
||||||
|
option(MCPI_HEADLESS_MODE "Headless Mode" ${MCPI_SERVER_MODE})
|
||||||
|
set(MCPI_BUILD_MODE "both" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code; \"both\" = Build All Code As ARM")
|
||||||
|
set_property(CACHE MCPI_BUILD_MODE PROPERTY STRINGS "both" "arm" "native")
|
||||||
|
option(MCPI_OPEN_SOURCE_ONLY "Only Install Open-Source Code (Will Result In Broken Install)" FALSE)
|
||||||
|
option(MCPI_IS_APPIMAGE_BUILD "AppImage Build" FALSE)
|
||||||
|
|
||||||
|
# Configure Build Mode
|
||||||
|
if(MCPI_BUILD_MODE STREQUAL "arm")
|
||||||
|
set(USE_ARM32_TOOLCHAIN TRUE)
|
||||||
|
set(BUILD_ARM_COMPONENTS TRUE)
|
||||||
|
set(BUILD_NATIVE_COMPONENTS FALSE)
|
||||||
|
elseif(MCPI_BUILD_MODE STREQUAL "native")
|
||||||
|
set(USE_ARM32_TOOLCHAIN FALSE)
|
||||||
|
set(BUILD_ARM_COMPONENTS FALSE)
|
||||||
|
set(BUILD_NATIVE_COMPONENTS TRUE)
|
||||||
|
elseif(MCPI_BUILD_MODE STREQUAL "both")
|
||||||
|
set(USE_ARM32_TOOLCHAIN TRUE)
|
||||||
|
set(BUILD_ARM_COMPONENTS TRUE)
|
||||||
|
set(BUILD_NATIVE_COMPONENTS TRUE)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Invalid Mode")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Core Options
|
# Utility Functions
|
||||||
include(cmake/options/core-options.cmake)
|
include(cmake/util.cmake)
|
||||||
|
|
||||||
|
# Specify Variant Name
|
||||||
|
set(MCPI_VARIANT_NAME "minecraft-pi-reborn")
|
||||||
|
if(MCPI_SERVER_MODE)
|
||||||
|
set(MCPI_VARIANT_NAME "${MCPI_VARIANT_NAME}-server")
|
||||||
|
else()
|
||||||
|
set(MCPI_VARIANT_NAME "${MCPI_VARIANT_NAME}-client")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Specify Installation Paths
|
||||||
|
set(MCPI_INSTALL_DIR "lib/${MCPI_VARIANT_NAME}")
|
||||||
|
set(MCPI_LIB_DIR "${MCPI_INSTALL_DIR}/lib")
|
||||||
|
set(MCPI_BIN_DIR "${MCPI_INSTALL_DIR}/bin")
|
||||||
|
|
||||||
# Build Mode
|
# Build Mode
|
||||||
if(NOT DEFINED CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
|
set(CMAKE_BUILD_TYPE "Release")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Start Project
|
# Start Project
|
||||||
project(minecraft-pi-reborn)
|
project(minecraft-pi-reborn)
|
||||||
|
|
||||||
# Utility Functions
|
# Require ARM Compilation
|
||||||
include(cmake/util/util.cmake)
|
if(USE_ARM32_TOOLCHAIN AND (NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "arm") AND (NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l"))
|
||||||
|
message(FATAL_ERROR "ARM-Targeting Compiler Required")
|
||||||
# Sanity Checks
|
|
||||||
string(CONCAT ARM_SANITY_CHECK
|
|
||||||
"include(CheckSymbolExists)\n"
|
|
||||||
"check_symbol_exists(\"__arm__\" \"\" IS_ARM_TARGETING)"
|
|
||||||
)
|
|
||||||
if(BUILD_ARM_COMPONENTS)
|
|
||||||
string(CONCAT ARM_SANITY_CHECK
|
|
||||||
"${ARM_SANITY_CHECK}\n"
|
|
||||||
"if(NOT IS_ARM_TARGETING)\n"
|
|
||||||
" message(FATAL_ERROR \"ARM-Targeting Compiler Required\")\n"
|
|
||||||
"endif()"
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
cmake_language(EVAL CODE "${ARM_SANITY_CHECK}")
|
|
||||||
|
|
||||||
# Extra Options
|
# Specify Default Installation Prefix
|
||||||
include(cmake/options/extra-options.cmake)
|
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||||
|
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Paths
|
# Optimizations
|
||||||
include(cmake/options/paths.cmake)
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
add_compile_options(-O3)
|
||||||
|
else()
|
||||||
|
add_compile_options(-g)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Required Compile Flags
|
# Use LLD When Using Clang
|
||||||
string(CONCAT COMPILE_FLAGS_SETUP
|
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||||
# Optimizations
|
add_link_options("-fuse-ld=lld")
|
||||||
"if(CMAKE_BUILD_TYPE STREQUAL \"Release\")\n"
|
endif()
|
||||||
" add_compile_options(-O3)\n"
|
|
||||||
" add_link_options(-s)\n"
|
|
||||||
"else()\n"
|
|
||||||
" add_compile_options(-g)\n"
|
|
||||||
"endif()\n"
|
|
||||||
|
|
||||||
# PIC
|
# PIC
|
||||||
"set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)\n"
|
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
|
||||||
|
|
||||||
# Warnings
|
|
||||||
"add_link_options(-Wl,--no-undefined)\n"
|
|
||||||
|
|
||||||
# C Standard
|
|
||||||
"add_definitions(-D_GNU_SOURCE)\n"
|
|
||||||
"set(CMAKE_C_STANDARD 99)\n"
|
|
||||||
"set(CMAKE_CXX_STANDARD 11)\n"
|
|
||||||
|
|
||||||
# Skip RPath
|
|
||||||
"set(CMAKE_SKIP_BUILD_RPATH TRUE)"
|
|
||||||
)
|
|
||||||
cmake_language(EVAL CODE "${COMPILE_FLAGS_SETUP}")
|
|
||||||
|
|
||||||
# Fast Math
|
# Fast Math
|
||||||
add_compile_options(-ffast-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")
|
|
||||||
# Prevents False Positives
|
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 10.0)
|
|
||||||
add_compile_options(-Wno-stringop-overflow)
|
|
||||||
endif()
|
|
||||||
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 11.0)
|
|
||||||
add_compile_options(-Wno-array-bounds -Wno-stringop-overread)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Buld Dependencies
|
# Buld Dependencies
|
||||||
add_subdirectory(dependencies)
|
add_subdirectory(dependencies)
|
||||||
|
|
||||||
|
# Warnings
|
||||||
|
add_compile_options(-Wall -Wextra -Werror -Wpointer-arith -Wshadow -Wnull-dereference)
|
||||||
|
add_link_options(-Wl,--no-undefined)
|
||||||
|
add_definitions(-D_GNU_SOURCE)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
|
# Specify Constants
|
||||||
|
if(MCPI_SERVER_MODE)
|
||||||
|
add_definitions(-DMCPI_SERVER_MODE)
|
||||||
|
endif()
|
||||||
|
if(MCPI_HEADLESS_MODE)
|
||||||
|
add_definitions(-DMCPI_HEADLESS_MODE)
|
||||||
|
endif()
|
||||||
|
if(MCPI_IS_APPIMAGE_BUILD)
|
||||||
|
add_definitions(-DMCPI_IS_APPIMAGE_BUILD)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Version
|
# Version
|
||||||
set_property(
|
file(STRINGS VERSION VERSION)
|
||||||
DIRECTORY
|
add_definitions(-DVERSION="${VERSION}")
|
||||||
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
|
# Build libreborn
|
||||||
add_subdirectory(libreborn)
|
add_subdirectory(libreborn)
|
||||||
|
@ -113,70 +123,3 @@ endif()
|
||||||
if(BUILD_ARM_COMPONENTS)
|
if(BUILD_ARM_COMPONENTS)
|
||||||
add_subdirectory(mods)
|
add_subdirectory(mods)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Include Images
|
|
||||||
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" EXPORT_LINK_INTERFACE_LIBRARIES)
|
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/sdk.cmake"
|
|
||||||
# Compile Flags
|
|
||||||
"${COMPILE_FLAGS_SETUP}\n"
|
|
||||||
# Snaity Check
|
|
||||||
"${ARM_SANITY_CHECK}\n"
|
|
||||||
# Log
|
|
||||||
"message(STATUS \"Using Reborn 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}")
|
|
||||||
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>/install")
|
|
||||||
if(NOT MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN)
|
|
||||||
if(DEFINED CMAKE_TOOLCHAIN_FILE)
|
|
||||||
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${CMAKE_TOOLCHAIN_FILE}")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
list(APPEND ARM_OPTIONS "-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${MCPI_CMAKE_TOOLCHAIN_FILE}")
|
|
||||||
endif()
|
|
||||||
list(APPEND ARM_OPTIONS "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}")
|
|
||||||
# Build
|
|
||||||
ExternalProject_Add(arm-components
|
|
||||||
DOWNLOAD_COMMAND ""
|
|
||||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
|
|
||||||
CMAKE_CACHE_ARGS ${ARM_OPTIONS}
|
|
||||||
INSTALL_COMMAND "${CMAKE_COMMAND}" "-E" "rm" "-rf" "<INSTALL_DIR>/install"
|
|
||||||
COMMAND
|
|
||||||
"${CMAKE_COMMAND}" "-E" "env"
|
|
||||||
"DESTDIR="
|
|
||||||
"${CMAKE_COMMAND}" "--install" "<BINARY_DIR>"
|
|
||||||
USES_TERMINAL_CONFIGURE TRUE
|
|
||||||
USES_TERMINAL_BUILD TRUE
|
|
||||||
USES_TERMINAL_INSTALL TRUE
|
|
||||||
BUILD_ALWAYS TRUE
|
|
||||||
)
|
|
||||||
# Install
|
|
||||||
ExternalProject_Get_Property(arm-components INSTALL_DIR)
|
|
||||||
install(DIRECTORY "${INSTALL_DIR}/install/${MCPI_INSTALL_DIR}/" DESTINATION "${MCPI_INSTALL_DIR}")
|
|
||||||
endif()
|
|
||||||
|
|
20
Dockerfile
20
Dockerfile
|
@ -3,12 +3,24 @@ FROM debian:bullseye-slim
|
||||||
# Install
|
# Install
|
||||||
RUN \
|
RUN \
|
||||||
apt-get update && \
|
apt-get update && \
|
||||||
apt-get install -y tini qemu-user && \
|
apt-get install -y tini sed && \
|
||||||
apt-get --fix-broken install -y && \
|
apt-get --fix-broken install -y && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Copy
|
# Copy AppImage
|
||||||
ADD ./out/server-amd64 /app
|
RUN mkdir /app
|
||||||
|
ADD ./out/minecraft-pi-reborn-server-*-amd64.AppImage /app
|
||||||
|
|
||||||
|
# Extract AppImage
|
||||||
|
WORKDIR /app
|
||||||
|
RUN \
|
||||||
|
sed -i '0,/AI\x02/{s|AI\x02|\x00\x00\x00|}' ./*.AppImage && \
|
||||||
|
./*.AppImage --appimage-extract && \
|
||||||
|
rm -f ./*.AppImage
|
||||||
|
|
||||||
|
# Setup AppImage
|
||||||
|
ENV OWD=/data
|
||||||
|
ENV APPDIR=/app/squashfs-root
|
||||||
|
|
||||||
# Setup Working Directory
|
# Setup Working Directory
|
||||||
RUN mkdir /data
|
RUN mkdir /data
|
||||||
|
@ -16,4 +28,4 @@ WORKDIR /data
|
||||||
|
|
||||||
# Setup Entrypoint
|
# Setup Entrypoint
|
||||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||||
CMD ["/app/usr/bin/minecraft-pi-reborn-server"]
|
CMD ["/app/squashfs-root/AppRun"]
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
pipeline {
|
||||||
|
agent none
|
||||||
|
stages {
|
||||||
|
stage('Debian Bullseye') {
|
||||||
|
agent {
|
||||||
|
dockerfile {
|
||||||
|
filename 'scripts/ci/Dockerfile'
|
||||||
|
args '-v /var/run/docker.sock:/var/run/docker.sock'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 'docker build --no-cache --tag thebrokenrail/minecraft-pi-reborn-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-server'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2024 TheBrokenRail
|
Copyright (c) 2022 TheBrokenRail
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
1
archives
1
archives
|
@ -1 +0,0 @@
|
||||||
Subproject commit 37d4baec5874b39e10cafda2f9fcf6b63129c85a
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Setup Toolchain
|
||||||
|
macro(setup_toolchain target)
|
||||||
|
# Use ARM Cross-Compiler
|
||||||
|
set(CMAKE_C_COMPILER "${target}-gcc")
|
||||||
|
set(CMAKE_CXX_COMPILER "${target}-g++")
|
||||||
|
set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}")
|
||||||
|
# Extra
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
# pkg-config
|
||||||
|
set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/${target}/pkgconfig:/usr/${target}/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig")
|
||||||
|
endmacro()
|
|
@ -1,62 +0,0 @@
|
||||||
# Downlaod 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/AppImageKit/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 Downlopad 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}"
|
|
||||||
"appimagetool"
|
|
||||||
"--updateinformation" "zsync|https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases/download/latest/${CPACK_PACKAGE_FILE_NAME_ZSYNC}.AppImage.zsync"
|
|
||||||
"--runtime-file" "${RUNTIME}"
|
|
||||||
"--comp" "xz"
|
|
||||||
"${CPACK_TEMPORARY_DIRECTORY}"
|
|
||||||
"${CPACK_PACKAGE_FILE_NAME}.AppImage"
|
|
||||||
WORKING_DIRECTORY "${CPACK_PACKAGE_DIRECTORY}"
|
|
||||||
RESULT_VARIABLE APPIMAGETOOL_RESULT
|
|
||||||
)
|
|
||||||
if(NOT APPIMAGETOOL_RESULT EQUAL 0)
|
|
||||||
message(FATAL_ERROR "Unable Package AppImage")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Rename ZSync File
|
|
||||||
file(RENAME "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}.AppImage.zsync" "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME_ZSYNC}.AppImage.zsync")
|
|
||||||
|
|
||||||
# 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}.AppImage")
|
|
||||||
check_file("${CPACK_PACKAGE_FILE_NAME_ZSYNC}.AppImage.zsync")
|
|
|
@ -1,38 +0,0 @@
|
||||||
# Determine Architecture
|
|
||||||
set(CPACK_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(CPACK_MCPI_ARCH "${name}" PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
check_arch("__arm__" "armhf")
|
|
||||||
check_arch("__aarch64__" "arm64")
|
|
||||||
check_arch("__x86_64__" "amd64")
|
|
||||||
|
|
||||||
# CPack
|
|
||||||
set(CPACK_PACKAGE_NAME "${MCPI_VARIANT_NAME}")
|
|
||||||
set(CPACK_PACKAGE_VENDOR "TheBrokenRail & Mojang AB")
|
|
||||||
set(CPACK_VERBATIM_VARIABLES TRUE)
|
|
||||||
set(CPACK_MONOLITHIC_INSTALL TRUE)
|
|
||||||
set(CPACK_PACKAGE_FILE_NAME "${MCPI_VARIANT_NAME}-${MCPI_VERSION}-${CPACK_MCPI_ARCH}")
|
|
||||||
set(CPACK_PACKAGE_FILE_NAME_ZSYNC "${MCPI_VARIANT_NAME}-latest-${CPACK_MCPI_ARCH}")
|
|
||||||
|
|
||||||
# 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")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Package
|
|
||||||
include(CPack)
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Warning
|
||||||
|
message(WARNING "i686 Builds Are Unsupported, Proceed At Your Own Risk")
|
||||||
|
# Compile For i686
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake")
|
||||||
|
# Use i686 Cross-Compiler
|
||||||
|
setup_toolchain("i686-linux-gnu")
|
||||||
|
# Details
|
||||||
|
set(CMAKE_SYSTEM_NAME "Linux")
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR "i686")
|
|
@ -1,21 +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()
|
|
|
@ -1,79 +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()
|
|
||||||
|
|
||||||
# Server/Headless Builds
|
|
||||||
mcpi_option(SERVER_MODE "Server Mode" BOOL FALSE)
|
|
||||||
mcpi_option(HEADLESS_MODE "Headless Mode" BOOL "${MCPI_SERVER_MODE}")
|
|
||||||
|
|
||||||
# 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
|
|
||||||
if(NOT MCPI_HEADLESS_MODE)
|
|
||||||
set(DEFAULT_USE_MEDIA_LAYER_PROXY FALSE)
|
|
||||||
if(BUILD_NATIVE_COMPONENTS AND NOT IS_ARM_TARGETING)
|
|
||||||
set(DEFAULT_USE_MEDIA_LAYER_PROXY TRUE)
|
|
||||||
endif()
|
|
||||||
mcpi_option(USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" BOOL "${DEFAULT_USE_MEDIA_LAYER_PROXY}")
|
|
||||||
mcpi_option(USE_GLES1_COMPATIBILITY_LAYER "Whether To Enable The GLESv1_CM Compatibility Layer" BOOL TRUE)
|
|
||||||
else()
|
|
||||||
set(MCPI_USE_MEDIA_LAYER_PROXY FALSE)
|
|
||||||
endif()
|
|
||||||
if(MCPI_USE_MEDIA_LAYER_PROXY)
|
|
||||||
set(BUILD_MEDIA_LAYER_CORE "${BUILD_NATIVE_COMPONENTS}")
|
|
||||||
else()
|
|
||||||
set(BUILD_MEDIA_LAYER_CORE "${BUILD_ARM_COMPONENTS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Specify Variant Name
|
|
||||||
set(MCPI_VARIANT_NAME "minecraft-pi-reborn")
|
|
||||||
if(MCPI_SERVER_MODE)
|
|
||||||
string(APPEND MCPI_VARIANT_NAME "-server")
|
|
||||||
else()
|
|
||||||
string(APPEND MCPI_VARIANT_NAME "-client")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# App ID
|
|
||||||
set(DEFAULT_APP_ID "com.thebrokenrail.MCPIReborn")
|
|
||||||
if(MCPI_SERVER_MODE)
|
|
||||||
string(APPEND DEFAULT_APP_ID "Server")
|
|
||||||
else()
|
|
||||||
string(APPEND DEFAULT_APP_ID "Client")
|
|
||||||
endif()
|
|
||||||
mcpi_option(APP_ID "App ID" STRING "${DEFAULT_APP_ID}")
|
|
||||||
|
|
||||||
# App Title
|
|
||||||
mcpi_option(APP_BASE_TITLE "Base App Title" STRING "Minecraft: Pi Edition: Reborn")
|
|
||||||
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()
|
|
||||||
mcpi_option(APP_TITLE "App Title" STRING "${DEFAULT_APP_TITLE}")
|
|
||||||
|
|
||||||
# Skin Server
|
|
||||||
mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data")
|
|
||||||
|
|
||||||
# QEMU
|
|
||||||
if(BUILD_NATIVE_COMPONENTS)
|
|
||||||
include(CheckSymbolExists)
|
|
||||||
check_symbol_exists("__ARM_ARCH" "" MCPI_IS_ARM32_OR_ARM64_TARGETING)
|
|
||||||
set(MCPI_USE_QEMU TRUE)
|
|
||||||
if(MCPI_IS_ARM32_OR_ARM64_TARGETING)
|
|
||||||
set(MCPI_USE_QEMU FALSE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
|
@ -1,33 +0,0 @@
|
||||||
# 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()
|
|
||||||
|
|
||||||
# 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 "" FORCE)
|
|
||||||
set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT FALSE)
|
|
||||||
endif()
|
|
|
@ -1,70 +0,0 @@
|
||||||
# Pick Archive
|
|
||||||
set(toolchain_version "13.2.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-arm-none-linux-gnueabihf.tar.xz")
|
|
||||||
elseif(arch STREQUAL "aarch64" OR arch STREQUAL "armv8b" OR arch STREQUAL "armv8l")
|
|
||||||
set(toolchain_file "arm-gnu-toolchain-${toolchain_version}-aarch64-arm-none-linux-gnueabihf.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/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(MCPI_CMAKE_TOOLCHAIN_FILE "${toolchain_dir}/toolchain.cmake" CACHE FILEPATH "" 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")
|
|
||||||
file(REMOVE_RECURSE "${sysroot_dir}/usr/lib/gconv")
|
|
||||||
|
|
||||||
# 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()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Install Sysroot (Skipping Empty Directories)
|
|
||||||
function(install_arm_sysroot)
|
|
||||||
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()
|
|
||||||
endfunction()
|
|
|
@ -1,37 +0,0 @@
|
||||||
# Setup Toolchain
|
|
||||||
macro(setup_toolchain target)
|
|
||||||
# Target Variants
|
|
||||||
set(target_variants "${target}")
|
|
||||||
macro(add_target_variant value)
|
|
||||||
string(REPLACE "-linux" "-${value}-linux" target_variant "${target}")
|
|
||||||
list(APPEND target_variants "${target_variant}")
|
|
||||||
endmacro()
|
|
||||||
add_target_variant(unknown)
|
|
||||||
add_target_variant(none)
|
|
||||||
add_target_variant(pc)
|
|
||||||
|
|
||||||
# Find Compiler
|
|
||||||
macro(find_compiler output name)
|
|
||||||
set(possible_names "")
|
|
||||||
foreach(possible_target IN LISTS target_variants)
|
|
||||||
list(APPEND possible_names "${possible_target}-${name}")
|
|
||||||
endforeach()
|
|
||||||
find_program(
|
|
||||||
"${output}"
|
|
||||||
NAMES ${possible_names}
|
|
||||||
NO_CACHE
|
|
||||||
)
|
|
||||||
if("${${output}}" STREQUAL "${output}-NOTFOUND")
|
|
||||||
message(FATAL_ERROR "Unable To Find ${name}")
|
|
||||||
endif()
|
|
||||||
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
|
|
||||||
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")
|
|
||||||
endmacro()
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Symlink Function
|
||||||
|
function(install_symlink target link)
|
||||||
|
install(CODE "\
|
||||||
|
# Prepare\n \
|
||||||
|
set(file \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${link}\")\n \
|
||||||
|
\
|
||||||
|
# Create Directory\n \
|
||||||
|
get_filename_component(dir \"\${file}\" DIRECTORY)\n \
|
||||||
|
file(MAKE_DIRECTORY \${dir})\n \
|
||||||
|
\
|
||||||
|
# Create Symlink\n \
|
||||||
|
if(NOT EXISTS \"\${file}\")\n \
|
||||||
|
execute_process(COMMAND \${CMAKE_COMMAND} -E create_symlink ${target} \"\${file}\")\n \
|
||||||
|
message(\"-- Installing: \${file}\")\n \
|
||||||
|
else()\n \
|
||||||
|
message(\"-- Up-to-date: \${file}\")\n \
|
||||||
|
endif() \
|
||||||
|
")
|
||||||
|
endfunction()
|
||||||
|
|
|
@ -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
|
|
||||||
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")
|
|
|
@ -1,33 +0,0 @@
|
||||||
# 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()
|
|
||||||
|
|
||||||
# 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()
|
|
|
@ -1,36 +1,22 @@
|
||||||
project(dependencies)
|
project(dependencies)
|
||||||
|
|
||||||
# stb_image
|
# ZLib
|
||||||
if(BUILD_ARM_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
|
if(BUILD_ARM_COMPONENTS)
|
||||||
add_subdirectory(stb_image)
|
add_subdirectory(zlib)
|
||||||
|
endif()
|
||||||
|
# LibPNG
|
||||||
|
if(BUILD_ARM_COMPONENTS)
|
||||||
|
add_subdirectory(libpng)
|
||||||
endif()
|
endif()
|
||||||
# Minecraft: Pi Edition
|
# Minecraft: Pi Edition
|
||||||
if(BUILD_ARM_COMPONENTS AND NOT MCPI_OPEN_SOURCE_ONLY)
|
if(BUILD_ARM_COMPONENTS AND NOT MCPI_OPEN_SOURCE_ONLY)
|
||||||
add_subdirectory(minecraft-pi)
|
add_subdirectory(minecraft-pi)
|
||||||
endif()
|
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 AND NOT MCPI_HEADLESS_MODE))
|
|
||||||
add_subdirectory(LIEF)
|
|
||||||
endif()
|
|
||||||
# QEMU
|
|
||||||
if(BUILD_NATIVE_COMPONENTS AND MCPI_USE_QEMU)
|
|
||||||
add_subdirectory(qemu)
|
|
||||||
endif()
|
|
||||||
# GLFW
|
# GLFW
|
||||||
if(BUILD_MEDIA_LAYER_CORE AND NOT MCPI_HEADLESS_MODE)
|
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
|
||||||
add_subdirectory(glfw)
|
add_subdirectory(glfw)
|
||||||
endif()
|
endif()
|
||||||
# GLES Compatibility Layer
|
# Zenity (Minimal Build)
|
||||||
if(BUILD_MEDIA_LAYER_CORE AND NOT MCPI_HEADLESS_MODE AND MCPI_USE_GLES1_COMPATIBILITY_LAYER)
|
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
|
||||||
add_subdirectory(gles-compatibility-layer)
|
add_subdirectory(zenity)
|
||||||
endif()
|
|
||||||
# UTF8-CPP
|
|
||||||
add_subdirectory(utf8cpp)
|
|
||||||
# Symbol Prcoessor
|
|
||||||
if(BUILD_ARM_COMPONENTS)
|
|
||||||
add_subdirectory(symbol-processor)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
project(LIEF)
|
|
||||||
|
|
||||||
# Silence Warnings
|
|
||||||
add_compile_options(-w -Wno-psabi)
|
|
||||||
|
|
||||||
## LIEF
|
|
||||||
|
|
||||||
# Options
|
|
||||||
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)
|
|
||||||
unset(MESSAGE_QUIET)
|
|
||||||
|
|
||||||
# Install
|
|
||||||
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")
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 16962f2f36a51b2acefad9cec3622f6de5730aa3
|
|
|
@ -1,7 +0,0 @@
|
||||||
project(gles-compatibility-layer)
|
|
||||||
|
|
||||||
# GLES Compatibility Layer
|
|
||||||
set(GLES_COMPATIBILITY_LAYER_USE_ES3 FALSE CACHE BOOL "" FORCE)
|
|
||||||
set(GLES_COMPATIBILITY_LAYER_USE_SDL FALSE CACHE BOOL "" FORCE)
|
|
||||||
set(GLES_COMPATIBILITY_LAYER_DEPENDENCY glfw CACHE STRING "" FORCE)
|
|
||||||
add_subdirectory(src)
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 67a8d026aa5aef062dae654d418c3cd09417c0c1
|
|
|
@ -6,22 +6,17 @@ add_compile_options(-w)
|
||||||
## GLFW
|
## GLFW
|
||||||
|
|
||||||
# Download
|
# Download
|
||||||
set(BUILD_SHARED_LIBS TRUE CACHE BOOL "" FORCE)
|
set(BUILD_SHARED_LIBS FALSE)
|
||||||
set(GLFW_BUILD_EXAMPLES FALSE CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_EXAMPLES FALSE)
|
||||||
set(GLFW_BUILD_TESTS FALSE CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_TESTS FALSE)
|
||||||
set(GLFW_BUILD_DOCS FALSE CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_DOCS FALSE)
|
||||||
set(GLFW_INSTALL FALSE CACHE BOOL "" FORCE)
|
set(GLFW_INSTALL FALSE)
|
||||||
set(GLFW_BUILD_WIN32 FALSE CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_WIN32 FALSE)
|
||||||
set(GLFW_BUILD_COCOA FALSE CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_COCOA FALSE)
|
||||||
set(GLFW_BUILD_X11 TRUE CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_X11 TRUE)
|
||||||
set(GLFW_BUILD_WAYLAND TRUE CACHE BOOL "" FORCE)
|
set(GLFW_BUILD_WAYLAND TRUE)
|
||||||
set(GLFW_LIBRARY_TYPE "SHARED" CACHE BOOL "" FORCE)
|
set(GLFW_LIBRARY_TYPE "STATIC")
|
||||||
set(MESSAGE_QUIET TRUE)
|
|
||||||
add_subdirectory(src EXCLUDE_FROM_ALL)
|
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||||
unset(MESSAGE_QUIET)
|
|
||||||
|
|
||||||
# Install
|
# Ensure Build
|
||||||
install(TARGETS glfw DESTINATION "${MCPI_LIB_DIR}")
|
add_custom_target(glfw-build ALL DEPENDS glfw)
|
||||||
|
|
||||||
# License
|
|
||||||
install(FILES src/LICENSE.md DESTINATION "${MCPI_LEGAL_DIR}/glfw")
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7b6aead9fb88b3623e3b3725ebb42670cbe4c579
|
Subproject commit 4cb36872a5fe448c205d0b46f0e8c8b57530cfe0
|
|
@ -0,0 +1,20 @@
|
||||||
|
project(libpng)
|
||||||
|
|
||||||
|
# Silence Warnings
|
||||||
|
add_compile_options(-w)
|
||||||
|
|
||||||
|
## LibPNG
|
||||||
|
|
||||||
|
# Download
|
||||||
|
set(ZLIB_LIBRARY zlibstatic)
|
||||||
|
set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../zlib/src" "${CMAKE_CURRENT_BINARY_DIR}/../zlib/src")
|
||||||
|
set(CMAKE_POLICY_DEFAULT_CMP0054 OLD) # Silence Warning
|
||||||
|
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||||
|
set(CMAKE_POLICY_DEFAULT_CMP0054 NEW) # Re-Enable New Behavior
|
||||||
|
set_target_properties(png12 PROPERTIES LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libpng.vers") # Use Symbol Versioning
|
||||||
|
set_target_properties(png12 PROPERTIES DEBUG_POSTFIX "") # Fix LibPNG Suffix In Debug Mode
|
||||||
|
|
||||||
|
# Ensure Build
|
||||||
|
add_custom_target(png12-build ALL DEPENDS png12)
|
||||||
|
# Install
|
||||||
|
install(TARGETS png12 DESTINATION "${MCPI_LIB_DIR}")
|
|
@ -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: *; };
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 5bb5bf345aef1e62adcfe30791f4364730a2aede
|
|
@ -12,18 +12,4 @@ FetchContent_Declare(
|
||||||
FetchContent_Populate(minecraft-pi)
|
FetchContent_Populate(minecraft-pi)
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
install(
|
install(DIRECTORY "${minecraft-pi_SOURCE_DIR}/" DESTINATION "${MCPI_INSTALL_DIR}" USE_SOURCE_PERMISSIONS)
|
||||||
DIRECTORY "${minecraft-pi_SOURCE_DIR}/"
|
|
||||||
DESTINATION "${MCPI_INSTALL_DIR}/game"
|
|
||||||
USE_SOURCE_PERMISSIONS
|
|
||||||
REGEX "api" EXCLUDE
|
|
||||||
REGEX "data" EXCLUDE
|
|
||||||
)
|
|
||||||
if(NOT MCPI_HEADLESS_MODE)
|
|
||||||
install(
|
|
||||||
DIRECTORY "${minecraft-pi_SOURCE_DIR}/data/"
|
|
||||||
DESTINATION "${MCPI_INSTALL_DIR}/game/data"
|
|
||||||
USE_SOURCE_PERMISSIONS
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
install_symlink("game/minecraft-pi" "${MCPI_INSTALL_DIR}/minecraft-pi")
|
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
project(qemu)
|
|
||||||
|
|
||||||
## QEMU
|
|
||||||
|
|
||||||
# Version
|
|
||||||
set(QEMU_VERSION "8.2.1")
|
|
||||||
|
|
||||||
# Flatpak Support
|
|
||||||
set(QEMU_PATCH "")
|
|
||||||
if(MCPI_IS_FLATPAK_BUILD)
|
|
||||||
set(QEMU_PATCH "sed" "-i" "s/libdrm/libdrm-dis/g" "<SOURCE_DIR>/meson.build")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Build
|
|
||||||
include(ExternalProject)
|
|
||||||
set(PKGCONFIG_ENV "")
|
|
||||||
if(DEFINED ENV{PKG_CONFIG_LIBDIR})
|
|
||||||
set(PKGCONFIG_ENV "PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}")
|
|
||||||
endif()
|
|
||||||
ExternalProject_Add(qemu
|
|
||||||
URL "${CMAKE_CURRENT_SOURCE_DIR}/../../archives/qemu-${QEMU_VERSION}.tar.xz"
|
|
||||||
CONFIGURE_COMMAND
|
|
||||||
"${CMAKE_COMMAND}" "-E" "env"
|
|
||||||
${PKGCONFIG_ENV}
|
|
||||||
"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 ninja "qemu-arm"
|
|
||||||
USES_TERMINAL_BUILD TRUE
|
|
||||||
INSTALL_COMMAND ""
|
|
||||||
TEST_COMMAND ""
|
|
||||||
PATCH_COMMAND ${QEMU_PATCH}
|
|
||||||
BUILD_BYPRODUCTS "<BINARY_DIR>/qemu-arm"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Install
|
|
||||||
ExternalProject_Get_property(qemu BINARY_DIR)
|
|
||||||
install(PROGRAMS "${BINARY_DIR}/qemu-arm" DESTINATION "${MCPI_BIN_DIR}")
|
|
||||||
|
|
||||||
# License
|
|
||||||
ExternalProject_Get_property(qemu SOURCE_DIR)
|
|
||||||
install(FILES "${SOURCE_DIR}/COPYING" DESTINATION "${MCPI_LEGAL_DIR}/qemu")
|
|
|
@ -1,30 +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_include_directories(
|
|
||||||
stb_image
|
|
||||||
PUBLIC
|
|
||||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
|
||||||
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/stb_image>"
|
|
||||||
)
|
|
||||||
target_link_libraries(stb_image PRIVATE m)
|
|
||||||
target_compile_definitions(stb_image PUBLIC STBI_ONLY_PNG)
|
|
||||||
|
|
||||||
# Install
|
|
||||||
install(TARGETS stb_image DESTINATION "${MCPI_LIB_DIR}")
|
|
||||||
install(
|
|
||||||
DIRECTORY "include/"
|
|
||||||
DESTINATION "${MCPI_SDK_INCLUDE_DIR}/stb_image"
|
|
||||||
FILES_MATCHING
|
|
||||||
PATTERN "*.h"
|
|
||||||
)
|
|
||||||
install(TARGETS stb_image EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
|
||||||
|
|
||||||
# License
|
|
||||||
install(FILES include/LICENSE DESTINATION "${MCPI_LEGAL_DIR}/stb_image")
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit beebb24b945efdea3b9bba23affb8eb3ba8982e7
|
|
|
@ -1,5 +0,0 @@
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
|
||||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
|
||||||
|
|
||||||
#include "stb_image.h"
|
|
||||||
#include "stb_image_write.h"
|
|
|
@ -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 9697b35de4d783282afdd3a4c643951ce49a0158
|
|
|
@ -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}/utf8cpp")
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit f6780f77f6824aa0fbe69f9b97ef7d8aba26ed92
|
|
|
@ -6,15 +6,10 @@ add_compile_options(-w)
|
||||||
## Zenity
|
## Zenity
|
||||||
|
|
||||||
# Download
|
# Download
|
||||||
set(MESSAGE_QUIET TRUE)
|
|
||||||
add_subdirectory(src EXCLUDE_FROM_ALL)
|
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||||
unset(MESSAGE_QUIET)
|
|
||||||
|
|
||||||
# Ensure Build
|
# Ensure Build
|
||||||
add_custom_target(zenity-build ALL DEPENDS zenity)
|
add_custom_target(zenity-build ALL DEPENDS zenity)
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
install(TARGETS zenity DESTINATION "${MCPI_BIN_DIR}")
|
install(TARGETS zenity DESTINATION "${MCPI_BIN_DIR}")
|
||||||
|
|
||||||
# License
|
|
||||||
install(FILES src/COPYING DESTINATION "${MCPI_LEGAL_DIR}/zenity")
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit a7496461161c917878d58131711425e7c8e59436
|
Subproject commit cdcc55e55f08956f6c5a5f3d63fce4614c75e8d4
|
|
@ -0,0 +1,12 @@
|
||||||
|
project(zlib)
|
||||||
|
|
||||||
|
# Silence Warnings
|
||||||
|
add_compile_options(-w)
|
||||||
|
|
||||||
|
## zlib
|
||||||
|
|
||||||
|
# Download
|
||||||
|
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# Ensure Build
|
||||||
|
add_custom_target(zlib-build ALL DEPENDS zlibstatic)
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 21767c654d31d2dccdde4330529775c6c5fd5389
|
|
@ -2,24 +2,16 @@
|
||||||
|
|
||||||
## Launch Sequence
|
## 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
|
### Client
|
||||||
1. The launcher is started by the user.
|
1. The launcher is started by the user
|
||||||
1. The launcher starts several Zenity dialogs to configure MCPI-Reborn.
|
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. The launcher replaces itself with MCPI
|
||||||
2. If a setting is cached, then the dialog's default value will be the cached value instead of the normal default.
|
1. MCPI-Reborn components are loaded using ``LD_PRELOAD`` and ``LD_LIBRARY_PATH``
|
||||||
3. When configuration has been completed, the settings specified will be cached.
|
2. If the Media Layer Proxy is enabled, the Media Layer Proxy Client is started as a sub-process
|
||||||
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
|
### Server
|
||||||
1. The launcher is started by the user.
|
1. The launcher is started by the user
|
||||||
2. The launcher replaces itself with MCPI.
|
2. The launcher replaces itself with MCPI
|
||||||
|
|
||||||
## Components
|
## Components
|
||||||
|
|
||||||
|
@ -27,11 +19,11 @@
|
||||||
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.
|
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:
|
The environmental variables configured by this component includes:
|
||||||
* `LD_PRELOAD`
|
* ``LD_PRELOAD``
|
||||||
* `LD_LIBRARY_PATH`
|
* ``LD_LIBRAR_PATH``
|
||||||
* `MCPI_FEATURE_FLAGS`
|
* ``MCPI_FEATURE_FLAGS``
|
||||||
* `MCPI_RENDER_DISTANCE`
|
* ``MCPI_RENDER_DISTANCE``
|
||||||
* `MCPI_USERNAME`
|
* ``MCPI_USERNAME``
|
||||||
|
|
||||||
This is always compiled for the host system's architecture.
|
This is always compiled for the host system's architecture.
|
||||||
|
|
||||||
|
@ -42,11 +34,12 @@ The Media Layer handles MCPI's graphics calls and user input. It replaces MCPI's
|
||||||
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.
|
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:
|
The utility functions include:
|
||||||
|
* Taking Screenshots
|
||||||
* Fullscreen
|
* Fullscreen
|
||||||
* Audio
|
* Audio
|
||||||
* Etc
|
* Etc
|
||||||
|
|
||||||
This is always compiled for the host system's architecture unless the Media Layer Proxy is disabled.
|
This is always compiled for the host system's architecture.
|
||||||
|
|
||||||
This was created because SDL 1.2 has numerous bugs and is in-general unsupported.
|
This was created because SDL 1.2 has numerous bugs and is in-general unsupported.
|
||||||
|
|
||||||
|
@ -67,22 +60,30 @@ It is made of two parts:
|
||||||
|
|
||||||
While proxying all Media Layer Core API calls across UNIX pipes does hurt performance, it is better than emulating the entire graphics stack.
|
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).
|
Using this in server-mode is redundant (and disallowed).
|
||||||
|
|
||||||
#### Extras
|
#### Extras
|
||||||
This sub-component contains code that must always be linked directly to MCPI.
|
This sub-component contains code that must always be linked directly to MCPI.
|
||||||
|
|
||||||
This is always compiled for ARM.
|
This is always compiled for ARM.
|
||||||
|
|
||||||
|
#### Stubs
|
||||||
|
This sub-component implements stubs for various redundant libraries used by MCPI to silence linker errors.
|
||||||
|
|
||||||
|
This is always compiled for ARM.
|
||||||
|
|
||||||
|
##### What To Stub And What To Patch?
|
||||||
|
Most libraries (like ``bcm_host``) can just be replaced with stubs, because they don't need to do anything and aren't used by anything else. However, some libraries (like EGL and X11) might be used by some of MCPI-Reborn's dependencies (like GLFW) so instead of being replaced by a stub, each call is manually patched out from MCPI. A stub is still generated just in case that library isn't present on the system to silence linker errors, but it is only loaded if no other version is available.
|
||||||
|
|
||||||
#### Headers
|
#### Headers
|
||||||
This sub-component includes headers for SDL, GLES, and EGL allowing easy (cross-)compilation.
|
This sub-component includes headers for SDL, GLES, and EGL allowing easy (cross-)compilation.
|
||||||
|
|
||||||
### Mods
|
### Mods
|
||||||
This component patches MCPI to modify its behavior. It's loaded using `LD_PRELOAD`.
|
This component links directly to MCPI and patches it to modify its behavior.
|
||||||
|
|
||||||
This is always compiled for ARM.
|
This is always compiled for ARM.
|
||||||
|
|
||||||
### `libreborn`
|
### ``libreborn``
|
||||||
This component contains various utility functions including:
|
This component contains various utility functions including:
|
||||||
|
|
||||||
* Code Patching (ARM Only)
|
* Code Patching (ARM Only)
|
||||||
|
@ -91,16 +92,18 @@ This component contains various utility functions including:
|
||||||
|
|
||||||
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).
|
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`
|
### ``symbols``
|
||||||
This component contains all MCPI symbols.
|
This component contains all MCPI symbols.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
MCPI-Reborn has several dependencies:
|
MCPI-Reborn has several dependencies:
|
||||||
* MCPI (Bundled)
|
* MCPI (Bundled)
|
||||||
* GLFW (Only In Client Mode; Bundled)
|
* GLFW (Only In Client Mode)
|
||||||
* OpenGL ES 2.0
|
* Open GL ES 1.1
|
||||||
|
* EGL
|
||||||
* OpenAL (Only In Client Mode)
|
* OpenAL (Only In Client Mode)
|
||||||
* ZLib (Required By LibPNG; Bundled)
|
* ZLib (Required By LibPNG; Bundled)
|
||||||
* LibPNG (Bundled)
|
* LibPNG (Bundled)
|
||||||
|
* FreeImage (Only In Client Mode)
|
||||||
* QEMU User Mode (Only On Non-ARM Hosts; Runtime Only)
|
* QEMU User Mode (Only On Non-ARM Hosts; Runtime Only)
|
||||||
* Zenity (Only In Client Mode; Runtime Only; Bundled)
|
* Zenity (Only In Client Mode; Runtime Only)
|
||||||
|
|
|
@ -1,13 +1,34 @@
|
||||||
# Building
|
# Building
|
||||||
|
|
||||||
## Dependencies
|
## Build Dependencies
|
||||||
|
* Common
|
||||||
|
* ARM Compiler
|
||||||
|
* Host Compiler (Clang)
|
||||||
|
* CMake
|
||||||
|
* Host Architecture Dependencies
|
||||||
|
* Client Mode Only
|
||||||
|
* GLFW
|
||||||
|
* FreeImage
|
||||||
|
* OpenAL
|
||||||
|
|
||||||
### Debian/Ubuntu
|
## Runtime Dependencies
|
||||||
```sh
|
* Non-ARM Host Architectures
|
||||||
./scripts/install-dependencies.sh
|
* QEMU User-Mode
|
||||||
```
|
* Host Architecture Dependencies
|
||||||
|
* CLient Mode Only
|
||||||
|
* OpenGL ES 1.1
|
||||||
|
* GLFW
|
||||||
|
* FreeImage
|
||||||
|
* OpenAL
|
||||||
|
* Zenity
|
||||||
|
|
||||||
## Instructions
|
## Instructions
|
||||||
```sh
|
```sh
|
||||||
./scripts/build.mjs <none|appimage|flatpak> <client|server> <armhf|arm64|amd64|host> [--clean] [--install] [-Dvar=value...]
|
./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>
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,194 +1,22 @@
|
||||||
# Changelog
|
# 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
|
|
||||||
* Add `Animated Lava` Feature Flag (Enabled By Default)
|
|
||||||
* Add `Animated Fire` Feature Flag (Enabled By Default)
|
|
||||||
* Add `Use Java Beta 1.3 Light Ramp` Feature Flag (Enabled By Default)
|
|
||||||
* Add `Send Full Level When Hosting Game` Feature Flag (Enabled By Default)
|
|
||||||
* Add `Food Overlay` Feature Flag (Disabled By Default)
|
|
||||||
* Add `Display Date In Select World Screen` Feature Flag (Enabled By Default)
|
|
||||||
* Add `Optimized Chunk Sorting` Feature Flag (Enabled By Default)
|
|
||||||
* Add `Add Cake` Feature Flag (Enabled By Default)
|
|
||||||
* Add `Add Reborn Info To Options` Feature Flag (Enabled By Default)
|
|
||||||
* Add `Track FPS` Feature Flag (Disabled By Default)
|
|
||||||
* 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)
|
|
||||||
* Add Milk Buckets
|
|
||||||
* Implement Crafting Remainders
|
|
||||||
* 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
|
|
||||||
* Add Splash Text To Start Screen
|
|
||||||
* `overwrite_calls` Now Scans VTables
|
|
||||||
|
|
||||||
**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
|
|
||||||
* Fix Crashing On ARMHF
|
|
||||||
* Heavily Improved Crash Report Dialog
|
|
||||||
|
|
||||||
**2.4.5**
|
|
||||||
* Bundle QEMU
|
|
||||||
|
|
||||||
**2.4.4**
|
|
||||||
* Cache Previous Launcher Configuration
|
|
||||||
* 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)
|
|
||||||
* 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)
|
|
||||||
* Improved Feature Flag Names
|
|
||||||
* Miscellaneous Bug Fixes
|
|
||||||
* Improved Build System
|
|
||||||
|
|
||||||
**2.4.3**
|
|
||||||
* Fix Signs With CP-437
|
|
||||||
|
|
||||||
**2.4.2**
|
|
||||||
* Fix Picking Up Lava
|
|
||||||
* Fix Wayland App ID
|
|
||||||
|
|
||||||
**2.4.1**
|
|
||||||
* Allow More Characters In Usernames And Chat
|
|
||||||
* Fix Running On ARMHF Debian Buster
|
|
||||||
|
|
||||||
**2.4.0**
|
|
||||||
* [Modding SDK](../example-mods/README.md)
|
|
||||||
* Cache Blacklist/Whitelist
|
|
||||||
* 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)
|
|
||||||
* Fix Sound Pitch/Volume/Attenuation
|
|
||||||
* Fix Holding Left-Click When Attacking
|
|
||||||
* Don't Force EGL (Should Fix Some NVIDIA Systems)
|
|
||||||
* Performance Fixes
|
|
||||||
|
|
||||||
**2.3.13**
|
|
||||||
* Fix Texture Bug
|
|
||||||
|
|
||||||
**2.3.12**
|
|
||||||
* Media Layer Proxy Optimizations
|
|
||||||
* Bug Fixes
|
|
||||||
|
|
||||||
**2.3.11**
|
|
||||||
* `--version` Command Line Option
|
|
||||||
* TPS Measured In Benchmark & Server
|
|
||||||
* Front-Facing Third-Person
|
|
||||||
* GLESv1 Comparability Layer
|
|
||||||
* Miscellaneous Bug Fixes
|
|
||||||
|
|
||||||
**2.3.10**
|
|
||||||
* Add Crash Report Dialog
|
|
||||||
* Disable V-Sync By Default
|
|
||||||
* Refactor Child Process Management
|
|
||||||
* Improve Build System
|
|
||||||
* Support For Building On Ubuntu 22.04
|
|
||||||
|
|
||||||
**2.3.9**
|
|
||||||
* Bundle An ARM Sysroot
|
|
||||||
* Not Used On ARM32 Systems
|
|
||||||
* Based On Debian Bullseye
|
|
||||||
* Colored Log Output
|
|
||||||
|
|
||||||
**2.3.8**
|
|
||||||
* Switch Up Mod Loading Order
|
|
||||||
|
|
||||||
**2.3.7**
|
|
||||||
* Don't Append Hyphens To New World Name, Only Folder Names
|
|
||||||
|
|
||||||
**2.3.6**
|
|
||||||
* 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)
|
|
||||||
* Custom World Names
|
|
||||||
* Game-Mode Selection
|
|
||||||
* Custom Seeds
|
|
||||||
|
|
||||||
**2.3.5**
|
|
||||||
* Renamed Some Feature Flags
|
|
||||||
* 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)
|
|
||||||
|
|
||||||
**2.3.4**
|
**2.3.4**
|
||||||
* AppImage Fixes
|
* AppImage Fixes
|
||||||
* Make Death Messages Customizable Server-Side
|
* Make Death Messages Customizable Server-Side
|
||||||
* Fix Q-Key Behavior Behavior When Editing Signs
|
* Fix Q-Key Behavior Behavior When Editing Signs
|
||||||
* Add `Force Touch Inventory` Feature Flag (Disabled By Default)
|
* Add ``Force Touch Inventory`` Feature Flag (Disabled By Default)
|
||||||
* Add `Fix Pause Menu` Feature Flag (Enabled By Default)
|
* Add ``Fix Pause Menu`` Feature Flag (Enabled By Default)
|
||||||
* Enables Server Visibility Toggle Button
|
* Enables Server Visibility Toggle Button
|
||||||
* Options Changes (Not Supported On Legacy)
|
* 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
|
* Adds Options Button To Classic UI Start Screen
|
||||||
* Removes Useless Options Toggles
|
* Removes Useless Options Toggles
|
||||||
* Fixes Options Toggles' Default Position
|
* Fixes Options Toggles' Default Position
|
||||||
* Store Multiple Settings In `options.txt`
|
* Store Multiple Settings In `options.txt`
|
||||||
* `Peaceful Mode` Feature Flag Moved To `game_difficulty`
|
* ``Peaceful Mode`` Feature Flag Moved To ``game_difficulty``
|
||||||
* `Smooth Lighting` Feature Flag Moved To `gfx_ao`
|
* ``Smooth Lighting`` Feature Flag Moved To ``gfx_ao``
|
||||||
* `Fancy Graphics` Feature Flag Moved To `gfx_fancygraphics`
|
* ``Fancy Graphics`` Feature Flag Moved To ``gfx_fancygraphics``
|
||||||
* `Disable Hosting LAN Worlds` Feature Flag Moved To `mp_server_visible_default`
|
* ``Disable Hosting LAN Worlds`` Feature Flag Moved To ``mp_server_visible_default``
|
||||||
|
|
||||||
**2.3.3**
|
**2.3.3**
|
||||||
* Add More Blocks To Expanded Creative Inventory
|
* Add More Blocks To Expanded Creative Inventory
|
||||||
|
@ -199,30 +27,30 @@
|
||||||
* Add More Blocks To Expanded Creative Inventory
|
* Add More Blocks To Expanded Creative Inventory
|
||||||
* Fix Nether Reactor With Creative Restrictions Disabled
|
* Fix Nether Reactor With Creative Restrictions Disabled
|
||||||
* Alphabetize Feature Flags
|
* Alphabetize Feature Flags
|
||||||
* Add `Disable V-Sync` Feature Flag (Disabled By Default)
|
* Add ``Disable V-Sync`` Feature Flag (Disabled By Default)
|
||||||
|
|
||||||
**2.3.1**
|
**2.3.1**
|
||||||
* Internal Refactor Of `libreborn`
|
* Internal Refactor Of ``libreborn``
|
||||||
* Remove Use Of `/bin/sh`
|
* Remove Use Of ``/bin/sh``
|
||||||
* Load Custom Mods First
|
* Load Custom Mods First
|
||||||
* Use Zenity Dark Mode
|
* 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**
|
**2.3.0**
|
||||||
* Switch To AppImage For Packaging
|
* Switch To AppImage For Packaging
|
||||||
* Prevent OpenAL From Crashing When Out Of Memory
|
* Prevent OpenAL From Crashing When Out Of Memory
|
||||||
* Vendor GLFW & Zenity
|
* Vendor GLFW & Zenity
|
||||||
* Seamless Wayland Support
|
* Seamless Wayland Support
|
||||||
* Add `MCPI_DEBUG` Environmental Variable
|
* Add ``MCPI_DEBUG`` Environmental Variable
|
||||||
* Add `Disable Hosting LAN Worlds` Feature Flag (Disabled By Default)
|
* Add ``Disable Hosting LAN Worlds`` Feature Flag (Disabled By Default)
|
||||||
* Add `Fix Furnace Not Checking Item Auxiliary` Feature Flag (Enabled 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 ``Disable Raw Mouse Motion (Not Recommended)`` Feature Flag (Disabled By Default) For Broken X11 Setups
|
||||||
* Added Back `~/.minecraft-pi/mods`
|
* Added Back `~/.minecraft-pi/mods`
|
||||||
* Improve Build System
|
* Improve Build System
|
||||||
* Improve Documentation
|
* Improve Documentation
|
||||||
|
|
||||||
**2.2.11**
|
**2.2.11**
|
||||||
* Add `Close Current Screen On Death` Feature Flag (Enabled By Default) To Prevent Bugs
|
* 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"
|
* Fix More Furnace UI Bugs When Using "Disable 'gui_blocks' Atlas"
|
||||||
|
|
||||||
**2.2.10**
|
**2.2.10**
|
||||||
|
@ -233,8 +61,8 @@
|
||||||
* Store Files In `/usr/lib`
|
* Store Files In `/usr/lib`
|
||||||
|
|
||||||
**2.2.8**
|
**2.2.8**
|
||||||
* Add `Hide Chat Messages` Optional Feature Flag
|
* Add ``Hide Chat Messages`` Optional Feature Flag
|
||||||
* Add `Remove Creative Mode Restrictions` Optional Feature Flag
|
* Add ``Remove Creative Mode Restrictions`` Optional Feature Flag
|
||||||
* Improve GLFW->SDL Mouse Motion Event Conversion
|
* Improve GLFW->SDL Mouse Motion Event Conversion
|
||||||
* Performance Optimizations
|
* Performance Optimizations
|
||||||
* Make Majority Of Server-Specific Logging Code Also Apply To The Client
|
* Make Majority Of Server-Specific Logging Code Also Apply To The Client
|
||||||
|
@ -266,15 +94,15 @@
|
||||||
* Make Missing Sound Event Cause Warning Rather Than Crash
|
* Make Missing Sound Event Cause Warning Rather Than Crash
|
||||||
|
|
||||||
**2.2.1**
|
**2.2.1**
|
||||||
* Prevent `random.burp` Sound From Crashing Game
|
* Prevent ``random.burp`` Sound From Crashing Game
|
||||||
* Always Cleanup Media Layer, Even On Crash
|
* Always Cleanup Media Layer, Even On Crash
|
||||||
* Resolve All Sounds On Startup
|
* Resolve All Sounds On Startup
|
||||||
|
|
||||||
**2.2.0**
|
**2.2.0**
|
||||||
* Sound Support
|
* 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
|
* 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
|
* Clean-Up Code
|
||||||
* Remove Support For Debian Buster
|
* Remove Support For Debian Buster
|
||||||
|
|
||||||
|
@ -291,7 +119,7 @@
|
||||||
* Print Error Message If RakNet Fails To Start
|
* Print Error Message If RakNet Fails To Start
|
||||||
|
|
||||||
**2.1.4**
|
**2.1.4**
|
||||||
* Fix `RakNet::RakString` Security Bug
|
* Fix ``RakNet::RakString`` Security Bug
|
||||||
|
|
||||||
**2.1.3**
|
**2.1.3**
|
||||||
* Workaround Broken Library Search Path On Some ARM 32-Bit Systems
|
* Workaround Broken Library Search Path On Some ARM 32-Bit Systems
|
||||||
|
@ -303,16 +131,16 @@
|
||||||
* Fix Symlink Code
|
* Fix Symlink Code
|
||||||
|
|
||||||
**2.1.0**
|
**2.1.0**
|
||||||
* Allow Binding `Q` Key To Item Dropping
|
* Allow Binding ``Q`` Key To Item Dropping
|
||||||
* Expose More Feature Flags
|
* Expose More Feature Flags
|
||||||
* Replace `Mob Spawning` Feature Flag With `Force Mob Spawning`
|
* Replace ``Mob Spawning`` Feature Flag With ``Force Mob Spawning``
|
||||||
* Fix `ESC` Key In Options Menu When `Miscellaneous Input Fixes` Is Enabled
|
* Fix ``ESC`` Key In Options Menu When ``Miscellaneous Input Fixes`` Is Enabled
|
||||||
|
|
||||||
**2.0.9**
|
**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**
|
**2.0.8**
|
||||||
* Use Default Port In `servers.txt` If Not Specified
|
* Use Default Port In ``servers.txt`` If Not Specified
|
||||||
|
|
||||||
**2.0.7**
|
**2.0.7**
|
||||||
* Fix Sign Text Not Updating In Multiplayer When Exiting Editing UI Using Escape Button
|
* Fix Sign Text Not Updating In Multiplayer When Exiting Editing UI Using Escape Button
|
||||||
|
@ -329,7 +157,7 @@
|
||||||
* Optimize Media Layer Proxy
|
* Optimize Media Layer Proxy
|
||||||
|
|
||||||
**2.0.3**
|
**2.0.3**
|
||||||
* Make `kill` Admin Command Print Death Message
|
* Make ``kill`` Admin Command Print Death Message
|
||||||
|
|
||||||
**2.0.2**
|
**2.0.2**
|
||||||
* Fix Mouse Cursor Bugs
|
* Fix Mouse Cursor Bugs
|
||||||
|
|
|
@ -2,19 +2,8 @@
|
||||||
|
|
||||||
## Command Line Arguments
|
## Command Line Arguments
|
||||||
|
|
||||||
### `--version` (Or `-v`)
|
### ``--print-available-feature-flags`` (Client Mode Only)
|
||||||
If you run MCPI-Reborn with `--version` it will print its version to `stdout`.
|
If you run MCPI-Reborn with ``--print-available-feature-flags``, it will print the available feature flags and then immediately exit.
|
||||||
|
|
||||||
### `--debug`
|
|
||||||
This sets `MCPI_DEBUG`.
|
|
||||||
|
|
||||||
### `--copy-sdk`
|
|
||||||
This extracts the modding SDK and immediately exits. (This allows the SDK to be extracted without starting the game.)
|
|
||||||
|
|
||||||
### Client Mode Only
|
|
||||||
|
|
||||||
#### `--print-available-feature-flags`
|
|
||||||
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:
|
The feature flags are printed in the following format:
|
||||||
```
|
```
|
||||||
|
@ -22,43 +11,29 @@ TRUE This Flag Is On By Default
|
||||||
FALSE This Flag Is Off By Default
|
FALSE This Flag Is Off By Default
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `--default`
|
### ``--only-generate`` (Server Mode Only)
|
||||||
This will skip the startup configuration dialogs and just use the default values. This will use the cached configuration unless `--no-cache` is used.
|
If you run MCPI-Reborn with ``--only-generate``, it will immediately exit once world generation has completed. This is mainly used for automatically testing MCPI-Reborn.
|
||||||
|
|
||||||
#### `--benchmark`
|
### ``--benchmark`` (Client Mode Only)
|
||||||
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.
|
If you run MCPI-Reborn with ``--benchmark``, it will 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.
|
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
|
## Environmental Variables
|
||||||
|
|
||||||
### `MCPI_DEBUG`
|
### ``MCPI_DEBUG``
|
||||||
This enables debug logging if it is set.
|
This enables debug logging if you set it to any non-zero-length value.
|
||||||
|
|
||||||
### `MCPI_API_PORT`
|
|
||||||
This configures the API to use a different port (the default is 4711).
|
|
||||||
|
|
||||||
### Client Mode Only
|
### Client Mode Only
|
||||||
If any of the following variables aren't set, one configuration dialog will open on startup for each unset variable.
|
If a value isn't set for any of the following variables, a GUI will open that allows you to select one.
|
||||||
|
|
||||||
#### `MCPI_FEATURE_FLAGS`
|
### ``MCPI_FEATURE_FLAGS``
|
||||||
This corresponds to `--print-available-feature-flags`. This is just a list of all enabled feature flags separated by `|`.
|
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*.
|
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`
|
### ``MCPI_RENDER_DISTANCE``
|
||||||
This is the render distance. The possible values are: `Far`, `Normal`, `Short`, and `Tiny`.
|
This is the render distance. The possible values are: ``Far``, ``Normal``, ``Short``, and ``Tiny``.
|
||||||
|
|
||||||
#### `MCPI_USERNAME`
|
### ``MCPI_USERNAME``
|
||||||
This is the username.
|
This is the username.
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
# In-Game Controls
|
|
||||||
|
|
||||||
## Keyboard & Mouse
|
|
||||||
| Action | Function |
|
|
||||||
| --- | --- |
|
|
||||||
| W | Move Forward |
|
|
||||||
| A | Move Left |
|
|
||||||
| S | Move Backward |
|
|
||||||
| D | Move Right |
|
|
||||||
| Space | Jump |
|
|
||||||
| Shift | Sneak |
|
|
||||||
| E | Open Inventory |
|
|
||||||
| Q | Drop Item |
|
|
||||||
| Ctrl+Q | Drop Item Stack |
|
|
||||||
| 1-9 | Select Item In Toolbar/Hotbar |
|
|
||||||
| Escape | Pause |
|
|
||||||
| Tab | Lock/Unlock Mouse |
|
|
||||||
| F11 | Fullscreen |
|
|
||||||
| F2 | Screenshot |
|
|
||||||
| F1 | Hide GUI |
|
|
||||||
| F5 | Change Perspective |
|
|
||||||
| T | Open Chat |
|
|
||||||
| Mouse Movement | Camera Control |
|
|
||||||
| 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.
|
|
|
@ -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.
|
|
|
@ -1,14 +1,17 @@
|
||||||
# Dedicated Server
|
# 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.6.1.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
To use, install and run the `minecraft-pi-reborn-server` AppImage. It will generate the world and `server.properties` in the current directory.
|
|
||||||
|
### Debian Package
|
||||||
|
To use, install and run ``minecraft-pi-reborn-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-server](https://hub.docker.com/r/thebrokenrail/minecraft-pi-reborn-server).
|
||||||
|
|
||||||
## Server Limitations
|
## Server Limitations
|
||||||
* Player data is not saved because of limitations with MCPE LAN worlds
|
* 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
|
* An easy workaround is to place your inventory in a chest before logging off
|
||||||
* Survival Mode servers are incompatible with unmodded MCPI
|
* Survival Mode servers are incompatible with unmodded MCPI
|
||||||
|
|
||||||
[^1]: The exception to this is buckets, those will crash MCPE players.
|
|
||||||
|
|
|
@ -1,30 +1,36 @@
|
||||||
# Installation
|
# Manual Installation
|
||||||
|
[Download Packages Here](https://jenkins.thebrokenrail.com/job/minecraft-pi-reborn/job/master/lastSuccessfulBuild/artifact/out/)
|
||||||
|
|
||||||
## AppImage
|
## Picking A Package
|
||||||
Download packages [here](https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/releases).
|
|
||||||
|
|
||||||
### System Requirements
|
### Name Format
|
||||||
* Debian Bullseye/Ubuntu 20.04 Or Higher
|
```
|
||||||
* FUSE 2
|
minecraft-pi-reborn-<Variant>_X.Y.Z_<Architecture>
|
||||||
* Debian/Ubuntu: `sudo apt install libfuse2`
|
```
|
||||||
* Arch: `sudo pacman -S fuse2`
|
|
||||||
* 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
|
### Picking A Variant
|
||||||
Follow [these](https://docs.appimage.org/introduction/quickstart.html#how-to-run-an-appimage) instructions.
|
* ``client``: Client mode, use this if you want to play MCPI
|
||||||
|
* ``server``: Server mode, use this if you want to host a dedicated MCPI server
|
||||||
|
|
||||||
## Flatpak
|
### Picking An Architecture
|
||||||
<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>
|
* ``amd64``: x86_64, use this if you are using a device with an AMD or Intel processor
|
||||||
|
* ``armhf``: ARM 32-Bit, use this if you are using an ARM device (like a Raspberry Pi)
|
||||||
|
* ``arm64``: ARM 64-Bit, ``armhf`` but for 64-bit devices
|
||||||
|
|
||||||
### Note
|
### Download and Install the app
|
||||||
Game data is stored in `~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi` instead of `~/.minecraft-pi`.
|
|
||||||
|
|
||||||
## Arch User Repository (Arch Linux Only)
|
Download with your favourite browser. You can run it directly from your Downloads folder, but for long-term use, and for use by multiple users, it's preferable to move the file to /opt. Open the Terminal (often Accessories-> Terminal, or CTRL+T) and enter:
|
||||||
The [`minecraft-pi-reborn-git`](https://aur.archlinux.org/packages/minecraft-pi-reborn-git) is available in the AUR.
|
```
|
||||||
|
sudo mv Downloads/minecraft-pi-reborn-client-2.3.4-arm64.AppImage /opt/
|
||||||
|
```
|
||||||
|
(replacing Downloads/minecraft-pi-reborn-client-2.3.4-arm64.AppImage with the file you downloaded).
|
||||||
|
|
||||||
|
To run, the file must be executable:
|
||||||
|
```
|
||||||
|
sudo chmod a+x /opt/minecraft-pi-reborn-client-2.3.4-arm64.AppImage
|
||||||
|
```
|
||||||
|
### Run the app
|
||||||
|
Enter the name of the AppImage to run, e.g.:
|
||||||
|
```
|
||||||
|
/opt/minecraft-pi-reborn-client-2.3.4-arm64.AppImage
|
||||||
|
```
|
||||||
|
|
|
@ -5,9 +5,9 @@ MCPI-Reborn supports two ways to play multiplayer.
|
||||||
This is also supported by vanilla MCPI. Just load a world in MCPI and other devices on the network can join.
|
This is also supported by vanilla MCPI. Just load a world in MCPI and other devices on the network can join.
|
||||||
|
|
||||||
## External Servers
|
## 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.
|
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`
|
### Example ``~/.minecraft-pi/servers.txt``
|
||||||
```
|
```
|
||||||
# Default Port Is 19132
|
# Default Port Is 19132
|
||||||
example.com
|
example.com
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
# Overriding Assets
|
# 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`[^1].
|
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
|
## Examples
|
||||||
- `data/images/terrain.png` -> `~/.minecraft-pi/overrides/images/terrain.png`
|
- ``data/images/terrain.png`` -> ``~/.minecraft-pi/overrides/images/terrain.png``
|
||||||
- `data/lang/en_US.lang` -> `~/.minecraft-pi/overrides/lang/en_US.lang`
|
- ``data/lang/en_US.lang`` -> ``~/.minecraft-pi/overrides/lang/en_US.lang``
|
||||||
|
|
||||||
[^1]: On Flatpak, the path is `~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi/overrides`.
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Documentation
|
# Documentation
|
||||||
* [View Installation](INSTALL.md)
|
* [View Manual Installation](INSTALL.md)
|
||||||
* [View Overriding Assets](OVERRIDING_ASSETS.md)
|
* [View Overriding Assets](OVERRIDING_ASSETS.md)
|
||||||
* [View Dedicated Server](DEDICATED_SERVER.md)
|
* [View Dedicated Server](DEDICATED_SERVER.md)
|
||||||
* [View Credits](CREDITS.md)
|
* [View Credits](CREDITS.md)
|
||||||
|
@ -9,6 +9,4 @@
|
||||||
* [View Command Line Arguments](COMMAND_LINE.md)
|
* [View Command Line Arguments](COMMAND_LINE.md)
|
||||||
* [View Multiplayer](MULTIPLAYER.md)
|
* [View Multiplayer](MULTIPLAYER.md)
|
||||||
* [View Sound](SOUND.md)
|
* [View Sound](SOUND.md)
|
||||||
* [View In-Game Controls](CONTROLS.md)
|
|
||||||
* [View Custom Skins](CUSTOM_SKINS.md)
|
|
||||||
* [View Changelog](CHANGELOG.md)
|
* [View Changelog](CHANGELOG.md)
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
# Sound
|
# Sound
|
||||||
One of MCPI-Reborn's main modifications is a sound-engine since MCPI does not include one by default[^1]. However, it can't be used out-of-box because MCPI does not contain any sound data and MCPI-Reborn can't include it because of copyright.
|
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.6.1[^2] APK file, just place its `libminecraftpe.so` into `~/.minecraft-pi/overrides`[^3] and you should have sound!
|
MCPE's sound data can be extracted from any MCPE v0.6.1[^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 does not actually do anything in un-modded MCPI, however it is connected to MCPI-Reborn's sound-engine.
|
[^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 is not a hard limit, an MCPE v0.8.1 APK would probably work, but don't rely on it.
|
[^2]: This isn't a hard limit, an MCPE v0.8.1 APK would probably work, but don't rely on it.
|
||||||
[^3]: On Flatpak, the path is `~/.var/app/com.thebrokenrail.MCPIReborn/.minecraft-pi/overrides`.
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
# Example Mods
|
|
||||||
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 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/lib/minecraft-pi-reborn-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/mods
|
|
||||||
```
|
|
|
@ -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
|
|
|
@ -1,15 +0,0 @@
|
||||||
/out
|
|
||||||
/debian/tmp
|
|
||||||
/.vscode
|
|
||||||
/build*
|
|
||||||
/CMakeLists.txt.user
|
|
||||||
*.autosave
|
|
||||||
/AppImageBuilder.yml
|
|
||||||
/appimage-builder-cache
|
|
||||||
/appimage-build
|
|
||||||
/AppDir
|
|
||||||
/*.zsync
|
|
||||||
/*.AppImage
|
|
||||||
/core*
|
|
||||||
/qemu_*
|
|
||||||
/cmake/.prebuilt-armhf-toolchain
|
|
|
@ -1,17 +0,0 @@
|
||||||
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-client/sdk/sdk.cmake")
|
|
||||||
|
|
||||||
# Build
|
|
||||||
add_library(chat-commands SHARED chat-commands.cpp)
|
|
||||||
target_link_libraries(chat-commands mods reborn-patch symbols)
|
|
|
@ -1,24 +0,0 @@
|
||||||
// Headers
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
#include <symbols/minecraft.h>
|
|
||||||
#include <mods/chat/chat.h>
|
|
||||||
#include <mods/misc/misc.h>
|
|
||||||
|
|
||||||
// The Actual Mod
|
|
||||||
HOOK(chat_handle_packet_send, void, (Minecraft *minecraft, ChatPacket *packet)) {
|
|
||||||
// Get Message
|
|
||||||
const char *message = packet->message.c_str();
|
|
||||||
if (message[0] == '/') {
|
|
||||||
// API Command
|
|
||||||
Gui *gui = &minecraft->gui;
|
|
||||||
std::string out = chat_send_api_command(minecraft, (char *) &message[1]);
|
|
||||||
if (out.length() > 0 && out[out.length() - 1] == '\n') {
|
|
||||||
out[out.length() - 1] = '\0';
|
|
||||||
}
|
|
||||||
gui->addMessage(&out);
|
|
||||||
} else {
|
|
||||||
// Call Original Method
|
|
||||||
ensure_chat_handle_packet_send();
|
|
||||||
real_chat_handle_packet_send(minecraft, packet);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
/out
|
|
||||||
/debian/tmp
|
|
||||||
/.vscode
|
|
||||||
/build*
|
|
||||||
/CMakeLists.txt.user
|
|
||||||
*.autosave
|
|
||||||
/AppImageBuilder.yml
|
|
||||||
/appimage-builder-cache
|
|
||||||
/appimage-build
|
|
||||||
/AppDir
|
|
||||||
/*.zsync
|
|
||||||
/*.AppImage
|
|
||||||
/core*
|
|
||||||
/qemu_*
|
|
||||||
/cmake/.prebuilt-armhf-toolchain
|
|
|
@ -1,17 +0,0 @@
|
||||||
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-client/sdk/sdk.cmake")
|
|
||||||
|
|
||||||
# Build
|
|
||||||
add_library(expanded-creative SHARED expanded-creative.cpp)
|
|
||||||
target_link_libraries(expanded-creative mods reborn-patch symbols)
|
|
|
@ -1,636 +0,0 @@
|
||||||
// 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) {
|
|
||||||
ItemInstance *fire_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(fire_instance);
|
|
||||||
fire_instance->count = 255;
|
|
||||||
fire_instance->auxiliary = 0;
|
|
||||||
fire_instance->id = 51;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
FillingContainer_addItem(filling_container, bread_instance);
|
|
||||||
|
|
||||||
ItemInstance *diamondHelm_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(diamondHelm_instance);
|
|
||||||
diamondHelm_instance->count = 255;
|
|
||||||
diamondHelm_instance->auxiliary = 0;
|
|
||||||
diamondHelm_instance->id = 310;
|
|
||||||
FillingContainer_addItem(filling_container, diamondHelm_instance);
|
|
||||||
|
|
||||||
ItemInstance *diamondChest_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(diamondChest_instance);
|
|
||||||
diamondChest_instance->count = 255;
|
|
||||||
diamondChest_instance->auxiliary = 0;
|
|
||||||
diamondChest_instance->id = 311;
|
|
||||||
FillingContainer_addItem(filling_container, diamondChest_instance);
|
|
||||||
|
|
||||||
ItemInstance *diamondLeg_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(diamondLeg_instance);
|
|
||||||
diamondLeg_instance->count = 255;
|
|
||||||
diamondLeg_instance->auxiliary = 0;
|
|
||||||
diamondLeg_instance->id = 312;
|
|
||||||
FillingContainer_addItem(filling_container, diamondLeg_instance);
|
|
||||||
|
|
||||||
ItemInstance *diamondBoot_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(diamondBoot_instance);
|
|
||||||
diamondBoot_instance->count = 255;
|
|
||||||
diamondBoot_instance->auxiliary = 0;
|
|
||||||
diamondBoot_instance->id = 313;
|
|
||||||
FillingContainer_addItem(filling_container, diamondBoot_instance);
|
|
||||||
|
|
||||||
ItemInstance *leatherCap_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(leatherCap_instance);
|
|
||||||
leatherCap_instance->count = 255;
|
|
||||||
leatherCap_instance->auxiliary = 0;
|
|
||||||
leatherCap_instance->id = 298;
|
|
||||||
FillingContainer_addItem(filling_container, leatherCap_instance);
|
|
||||||
|
|
||||||
ItemInstance *leatherShirt_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(leatherShirt_instance);
|
|
||||||
leatherShirt_instance->count = 255;
|
|
||||||
leatherShirt_instance->auxiliary = 0;
|
|
||||||
leatherShirt_instance->id = 299;
|
|
||||||
FillingContainer_addItem(filling_container, leatherShirt_instance);
|
|
||||||
|
|
||||||
ItemInstance *leatherPants_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(leatherPants_instance);
|
|
||||||
leatherPants_instance->count = 255;
|
|
||||||
leatherPants_instance->auxiliary = 0;
|
|
||||||
leatherPants_instance->id = 300;
|
|
||||||
FillingContainer_addItem(filling_container, leatherPants_instance);
|
|
||||||
|
|
||||||
ItemInstance *leatherBoots_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(leatherBoots_instance);
|
|
||||||
leatherBoots_instance->count = 255;
|
|
||||||
leatherBoots_instance->auxiliary = 0;
|
|
||||||
leatherBoots_instance->id = 301;
|
|
||||||
FillingContainer_addItem(filling_container, leatherBoots_instance);
|
|
||||||
|
|
||||||
ItemInstance *chainHelm_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(chainHelm_instance);
|
|
||||||
chainHelm_instance->count = 255;
|
|
||||||
chainHelm_instance->auxiliary = 0;
|
|
||||||
chainHelm_instance->id = 302;
|
|
||||||
FillingContainer_addItem(filling_container, chainHelm_instance);
|
|
||||||
|
|
||||||
ItemInstance *chainShirt_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(chainShirt_instance);
|
|
||||||
chainShirt_instance->count = 255;
|
|
||||||
chainShirt_instance->auxiliary = 0;
|
|
||||||
chainShirt_instance->id = 303;
|
|
||||||
FillingContainer_addItem(filling_container, chainShirt_instance);
|
|
||||||
|
|
||||||
ItemInstance *chainLegs_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(chainLegs_instance);
|
|
||||||
chainLegs_instance->count = 255;
|
|
||||||
chainLegs_instance->auxiliary = 0;
|
|
||||||
chainLegs_instance->id = 304;
|
|
||||||
FillingContainer_addItem(filling_container, chainLegs_instance);
|
|
||||||
|
|
||||||
ItemInstance *chainBoots_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(chainBoots_instance);
|
|
||||||
chainBoots_instance->count = 255;
|
|
||||||
chainBoots_instance->auxiliary = 0;
|
|
||||||
chainBoots_instance->id = 305;
|
|
||||||
FillingContainer_addItem(filling_container, chainBoots_instance);
|
|
||||||
|
|
||||||
ItemInstance *goldHelm_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(goldHelm_instance);
|
|
||||||
goldHelm_instance->count = 255;
|
|
||||||
goldHelm_instance->auxiliary = 0;
|
|
||||||
goldHelm_instance->id = 314;
|
|
||||||
FillingContainer_addItem(filling_container, goldHelm_instance);
|
|
||||||
|
|
||||||
ItemInstance *goldChest_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(goldChest_instance);
|
|
||||||
goldChest_instance->count = 255;
|
|
||||||
goldChest_instance->auxiliary = 0;
|
|
||||||
goldChest_instance->id = 315;
|
|
||||||
FillingContainer_addItem(filling_container, goldChest_instance);
|
|
||||||
|
|
||||||
ItemInstance *goldLegs_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(goldLegs_instance);
|
|
||||||
goldLegs_instance->count = 255;
|
|
||||||
goldLegs_instance->auxiliary = 0;
|
|
||||||
goldLegs_instance->id = 316;
|
|
||||||
FillingContainer_addItem(filling_container, goldLegs_instance);
|
|
||||||
|
|
||||||
ItemInstance *goldBoots_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(goldBoots_instance);
|
|
||||||
goldBoots_instance->count = 255;
|
|
||||||
goldBoots_instance->auxiliary = 0;
|
|
||||||
goldBoots_instance->id = 317;
|
|
||||||
FillingContainer_addItem(filling_container, goldBoots_instance);
|
|
||||||
|
|
||||||
ItemInstance *ironHelm_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(ironHelm_instance);
|
|
||||||
ironHelm_instance->count = 255;
|
|
||||||
ironHelm_instance->auxiliary = 0;
|
|
||||||
ironHelm_instance->id = 306;
|
|
||||||
FillingContainer_addItem(filling_container, ironHelm_instance);
|
|
||||||
|
|
||||||
ItemInstance *ironChest_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(ironChest_instance);
|
|
||||||
ironChest_instance->count = 255;
|
|
||||||
ironChest_instance->auxiliary = 0;
|
|
||||||
ironChest_instance->id = 307;
|
|
||||||
FillingContainer_addItem(filling_container, ironChest_instance);
|
|
||||||
|
|
||||||
ItemInstance *ironLegs_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(ironLegs_instance);
|
|
||||||
ironLegs_instance->count = 255;
|
|
||||||
ironLegs_instance->auxiliary = 0;
|
|
||||||
ironLegs_instance->id = 308;
|
|
||||||
FillingContainer_addItem(filling_container, ironLegs_instance);
|
|
||||||
|
|
||||||
ItemInstance *ironBoots_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(ironBoots_instance);
|
|
||||||
ironBoots_instance->count = 255;
|
|
||||||
ironBoots_instance->auxiliary = 0;
|
|
||||||
ironBoots_instance->id = 309;
|
|
||||||
FillingContainer_addItem(filling_container, ironBoots_instance);
|
|
||||||
|
|
||||||
ItemInstance *flint2_instance = new ItemInstance;
|
|
||||||
ALLOC_CHECK(flint2_instance);
|
|
||||||
flint2_instance->count = 255;
|
|
||||||
flint2_instance->auxiliary = 0;
|
|
||||||
flint2_instance->id = 318;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
FillingContainer_addItem(filling_container, chickenRaw_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init
|
|
||||||
__attribute__((constructor)) static void init_expanded_creative() {
|
|
||||||
INFO("Loading Expanded Creative Mod");
|
|
||||||
misc_run_on_creative_inventory_setup(Inventory_setupDefault_FillingContainer_addItem_call_injection);
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
/out
|
|
||||||
/debian/tmp
|
|
||||||
/.vscode
|
|
||||||
/build*
|
|
||||||
/CMakeLists.txt.user
|
|
||||||
*.autosave
|
|
||||||
/AppImageBuilder.yml
|
|
||||||
/appimage-builder-cache
|
|
||||||
/appimage-build
|
|
||||||
/AppDir
|
|
||||||
/*.zsync
|
|
||||||
/*.AppImage
|
|
||||||
/core*
|
|
||||||
/qemu_*
|
|
||||||
/cmake/.prebuilt-armhf-toolchain
|
|
|
@ -1,17 +0,0 @@
|
||||||
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-client/sdk/sdk.cmake")
|
|
||||||
|
|
||||||
# Build
|
|
||||||
add_library(recipes SHARED recipes.cpp)
|
|
||||||
target_link_libraries(recipes mods reborn-util symbols)
|
|
|
@ -1,57 +0,0 @@
|
||||||
// Headers
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
#include <symbols/minecraft.h>
|
|
||||||
#include <mods/misc/misc.h>
|
|
||||||
|
|
||||||
// Custom Crafting Recipes
|
|
||||||
static void Recipes_injection(Recipes *recipes) {
|
|
||||||
// Add
|
|
||||||
Recipes_Type type1 = {
|
|
||||||
.item = 0,
|
|
||||||
.tile = 0,
|
|
||||||
.instance = {
|
|
||||||
.count = 1,
|
|
||||||
.id = 12,
|
|
||||||
.auxiliary = 0
|
|
||||||
},
|
|
||||||
.letter = 'a'
|
|
||||||
};
|
|
||||||
Recipes_Type type2 = {
|
|
||||||
.item = 0,
|
|
||||||
.tile = 0,
|
|
||||||
.instance = {
|
|
||||||
.count = 1,
|
|
||||||
.id = 13,
|
|
||||||
.auxiliary = 0
|
|
||||||
},
|
|
||||||
.letter = 'b'
|
|
||||||
};
|
|
||||||
ItemInstance result = {
|
|
||||||
.count = 1,
|
|
||||||
.id = 344,
|
|
||||||
.auxiliary = 0
|
|
||||||
};
|
|
||||||
std::vector<Recipes_Type> types = {type1, type2};
|
|
||||||
Recipes_addShapelessRecipe(recipes, &result, &types);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom Furnace Recipes
|
|
||||||
static void FurnaceRecipes_injection(FurnaceRecipes *recipes) {
|
|
||||||
// Add
|
|
||||||
ItemInstance result = {
|
|
||||||
.count = 1,
|
|
||||||
.id = 246,
|
|
||||||
.auxiliary = 0
|
|
||||||
};
|
|
||||||
FurnaceRecipes_addFurnaceRecipe(recipes, 49, &result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init
|
|
||||||
__attribute__((constructor)) static void init_recipes() {
|
|
||||||
// Log
|
|
||||||
INFO("Loading Custom Recipes");
|
|
||||||
|
|
||||||
// Setup
|
|
||||||
misc_run_on_recipes_setup(Recipes_injection);
|
|
||||||
misc_run_on_furnace_recipes_setup(FurnaceRecipes_injection);
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
project(images)
|
|
||||||
|
|
||||||
# Title Background
|
|
||||||
if(NOT MCPI_HEADLESS_MODE)
|
|
||||||
install(
|
|
||||||
FILES "background.png"
|
|
||||||
DESTINATION "${MCPI_INSTALL_DIR}/data/images/gui"
|
|
||||||
RENAME "titleBG.png"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Chest Model
|
|
||||||
if(NOT MCPI_HEADLESS_MODE)
|
|
||||||
install(
|
|
||||||
FILES "chest.png"
|
|
||||||
DESTINATION "${MCPI_INSTALL_DIR}/data/images/item"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Icon
|
|
||||||
install(
|
|
||||||
FILES "icon.png"
|
|
||||||
DESTINATION "${MCPI_SHARE_DIR}/icons/hicolor/scalable/apps"
|
|
||||||
RENAME "${MCPI_APP_ID}.png"
|
|
||||||
)
|
|
||||||
|
|
||||||
# AppImage
|
|
||||||
if(MCPI_IS_APPIMAGE_BUILD)
|
|
||||||
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: 283 KiB |
BIN
images/chest.png
BIN
images/chest.png
Binary file not shown.
Before Width: | Height: | Size: 5.8 KiB |
BIN
images/icon.png
BIN
images/icon.png
Binary file not shown.
Before Width: | Height: | Size: 117 KiB |
BIN
images/start.png
BIN
images/start.png
Binary file not shown.
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 31 KiB |
|
@ -1,125 +1,32 @@
|
||||||
project(launcher)
|
project(launcher)
|
||||||
|
|
||||||
# Launcher
|
# Launcher
|
||||||
add_executable(launcher
|
if(BUILD_NATIVE_COMPONENTS)
|
||||||
src/bootstrap.c
|
add_executable(launcher src/bootstrap.c src/patchelf.c)
|
||||||
src/patchelf.cpp
|
if(MCPI_SERVER_MODE)
|
||||||
src/util.c
|
target_sources(launcher PRIVATE src/server/launcher.c)
|
||||||
src/crash-report.c
|
else()
|
||||||
src/sdk.c
|
target_sources(launcher PRIVATE src/client/launcher.cpp)
|
||||||
src/mods.c
|
endif()
|
||||||
)
|
target_link_libraries(launcher reborn-util)
|
||||||
if(MCPI_SERVER_MODE)
|
# Install
|
||||||
target_sources(launcher PRIVATE src/server/launcher.c)
|
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")
|
||||||
else()
|
install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_VARIANT_NAME}")
|
||||||
embed_resource(launcher src/client/available-feature-flags)
|
set(ICON_PATH "data/com.thebrokenrail.MCPIReborn.png")
|
||||||
target_sources(launcher PRIVATE
|
set(ICON_TARGET_PATH "share/icons/hicolor/scalable/apps")
|
||||||
src/client/launcher.cpp
|
if(NOT MCPI_SERVER_MODE)
|
||||||
src/client/cache.cpp
|
install(DIRECTORY "data/client/" DESTINATION ".")
|
||||||
src/client/available-feature-flags # Show In IDE
|
install(
|
||||||
)
|
FILES "${ICON_PATH}"
|
||||||
endif()
|
DESTINATION "${ICON_TARGET_PATH}"
|
||||||
target_link_libraries(launcher reborn-util LIB_LIEF)
|
RENAME "com.thebrokenrail.MCPIRebornClient.png"
|
||||||
# RPath
|
)
|
||||||
set_target_properties(launcher PROPERTIES INSTALL_RPATH "$ORIGIN/lib/native")
|
else()
|
||||||
|
install(DIRECTORY "data/server/" DESTINATION ".")
|
||||||
# Install
|
install(
|
||||||
install(TARGETS launcher DESTINATION "${MCPI_INSTALL_DIR}")
|
FILES "${ICON_PATH}"
|
||||||
install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_VARIANT_NAME}")
|
DESTINATION "${ICON_TARGET_PATH}"
|
||||||
|
RENAME "com.thebrokenrail.MCPIRebornServer.png"
|
||||||
# Install Desktop Entry
|
)
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/launcher.desktop"
|
endif()
|
||||||
"[Desktop Entry]\n"
|
|
||||||
"Name=${MCPI_APP_TITLE}\n"
|
|
||||||
"Comment=Fun with Blocks\n"
|
|
||||||
"Icon=${MCPI_APP_ID}\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"
|
|
||||||
RENAME "${MCPI_APP_ID}.desktop"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Install AppStream Metadata
|
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
|
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
|
||||||
"<component type=\"desktop\">\n"
|
|
||||||
" <id>${MCPI_APP_ID}</id>\n"
|
|
||||||
" <name>${MCPI_APP_TITLE}</name>\n"
|
|
||||||
" <metadata_license>CC0-1.0</metadata_license>\n"
|
|
||||||
" <summary>Fun with Blocks</summary>\n"
|
|
||||||
" <description>\n"
|
|
||||||
" <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\">https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn</url>\n"
|
|
||||||
" <launchable type=\"desktop-id\">${MCPI_APP_ID}.desktop</launchable>\n"
|
|
||||||
" <provides>\n"
|
|
||||||
" <id>com.thebrokenrail.MCPIRebornClient.desktop</id>\n"
|
|
||||||
" </provides>\n"
|
|
||||||
" <project_license>LicenseRef-proprietary</project_license>\n"
|
|
||||||
" <developer_name>TheBrokenRail & 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"
|
|
||||||
" <content_attribute id=\"violence-realistic\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"violence-bloodshed\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"violence-sexual\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"drugs-alcohol\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"drugs-narcotics\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"drugs-tobacco\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"sex-nudity\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"sex-themes\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"language-profanity\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"language-humor\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"language-discrimination\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"social-chat\">intense</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"social-info\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"social-audio\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"social-location\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"social-contacts\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"money-purchasing\">none</content_attribute>\n"
|
|
||||||
" <content_attribute id=\"money-gambling\">none</content_attribute>\n"
|
|
||||||
" </content_rating>\n"
|
|
||||||
" <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>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(
|
|
||||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/appstream.xml"
|
|
||||||
DESTINATION "${MCPI_SHARE_DIR}/metainfo"
|
|
||||||
RENAME "${MCPI_APP_ID}.appdata.xml"
|
|
||||||
)
|
|
||||||
|
|
||||||
# AppImage
|
|
||||||
if(MCPI_IS_APPIMAGE_BUILD)
|
|
||||||
install_symlink("bin/${MCPI_VARIANT_NAME}" "AppRun")
|
|
||||||
install_symlink("${MCPI_SHARE_DIR}/applications/${MCPI_APP_ID}.desktop" "${MCPI_APP_ID}.desktop")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
TRUE Touch GUI
|
||||||
|
TRUE Fix Bow & Arrow
|
||||||
|
TRUE Fix Attacking
|
||||||
|
FALSE Force Mob Spawning
|
||||||
|
TRUE Disable Autojump By Default
|
||||||
|
TRUE Display Nametags By Default
|
||||||
|
TRUE Fix Sign Placement
|
||||||
|
TRUE Show Block Outlines
|
||||||
|
FALSE Expand Creative Inventory
|
||||||
|
FALSE Remove Creative Mode Restrictions
|
||||||
|
TRUE Animated Water
|
||||||
|
TRUE Remove Invalid Item Background
|
||||||
|
TRUE Disable "gui_blocks" Atlas
|
||||||
|
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 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
|
||||||
|
TRUE Improved Cursor Rendering
|
||||||
|
FALSE Disable V-Sync
|
||||||
|
TRUE Fix Options Screen
|
||||||
|
FALSE Force Touch Inventory
|
||||||
|
TRUE Fix Pause Menu
|
|
@ -0,0 +1,10 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Minecraft: Pi Edition: Reborn (Client)
|
||||||
|
Comment=Fun with Blocks
|
||||||
|
Icon=com.thebrokenrail.MCPIRebornClient
|
||||||
|
StartupNotify=false
|
||||||
|
StartupWMClass=Minecraft: Pi Edition: Reborn
|
||||||
|
Exec=minecraft-pi-reborn-client
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Categories=Game;
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<component type="desktop">
|
||||||
|
<id>com.thebrokenrail.MCPIRebornClient</id>
|
||||||
|
<name>Minecraft: Pi Edition: Reborn (Client)</name>
|
||||||
|
<metadata_license>CC0-1.0</metadata_license>
|
||||||
|
<summary>Fun with Blocks</summary>
|
||||||
|
<description><p>Minecraft: Pi Edition Modding Project.</p><p>NOTE: This is not verified by, affiliated with, or supported by Mojang or Microsoft.</p></description>
|
||||||
|
<url type="homepage">https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn</url>
|
||||||
|
<screenshots>
|
||||||
|
<screenshot type="default">
|
||||||
|
<image>https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn/raw/branch/master/images/start.png</image>
|
||||||
|
</screenshot>
|
||||||
|
</screenshots>
|
||||||
|
<launchable type="desktop-id">com.thebrokenrail.MCPIRebornClient.desktop</launchable>
|
||||||
|
<provides>
|
||||||
|
<id>com.thebrokenrail.MCPIRebornClient.desktop</id>
|
||||||
|
</provides>
|
||||||
|
<project_license>LicenseRef-proprietary</project_license>
|
||||||
|
<developer_name>TheBrokenRail & Mojang AB</developer_name>
|
||||||
|
<content_rating type="oars-1.0">
|
||||||
|
<content_attribute id="violence-cartoon">moderate</content_attribute>
|
||||||
|
<content_attribute id="violence-fantasy">none</content_attribute>
|
||||||
|
<content_attribute id="violence-realistic">none</content_attribute>
|
||||||
|
<content_attribute id="violence-bloodshed">none</content_attribute>
|
||||||
|
<content_attribute id="violence-sexual">none</content_attribute>
|
||||||
|
<content_attribute id="drugs-alcohol">none</content_attribute>
|
||||||
|
<content_attribute id="drugs-narcotics">none</content_attribute>
|
||||||
|
<content_attribute id="drugs-tobacco">none</content_attribute>
|
||||||
|
<content_attribute id="sex-nudity">none</content_attribute>
|
||||||
|
<content_attribute id="sex-themes">none</content_attribute>
|
||||||
|
<content_attribute id="language-profanity">none</content_attribute>
|
||||||
|
<content_attribute id="language-humor">none</content_attribute>
|
||||||
|
<content_attribute id="language-discrimination">none</content_attribute>
|
||||||
|
<content_attribute id="social-chat">intense</content_attribute>
|
||||||
|
<content_attribute id="social-info">none</content_attribute>
|
||||||
|
<content_attribute id="social-audio">none</content_attribute>
|
||||||
|
<content_attribute id="social-location">none</content_attribute>
|
||||||
|
<content_attribute id="social-contacts">none</content_attribute>
|
||||||
|
<content_attribute id="money-purchasing">none</content_attribute>
|
||||||
|
<content_attribute id="money-gambling">none</content_attribute>
|
||||||
|
</content_rating>
|
||||||
|
</component>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
|
@ -0,0 +1,9 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Minecraft: Pi Edition: Reborn (Server)
|
||||||
|
Comment=Fun with Blocks
|
||||||
|
Icon=com.thebrokenrail.MCPIRebornServer
|
||||||
|
Exec=minecraft-pi-reborn-server
|
||||||
|
Terminal=true
|
||||||
|
Type=Application
|
||||||
|
Categories=Game;
|
||||||
|
NoDisplay=true
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<component type="desktop">
|
||||||
|
<id>com.thebrokenrail.MCPIRebornServer</id>
|
||||||
|
<name>Minecraft: Pi Edition: Reborn (Server)</name>
|
||||||
|
<metadata_license>CC0-1.0</metadata_license>
|
||||||
|
<summary>Fun with Blocks</summary>
|
||||||
|
<description><p>Minecraft: Pi Edition Modding Project.</p><p>NOTE: This is not verified by, affiliated with, or supported by Mojang or Microsoft.</p></description>
|
||||||
|
<url type="homepage">https://gitea.thebrokenrail.com/TheBrokenRail/minecraft-pi-reborn</url>
|
||||||
|
<launchable type="desktop-id">com.thebrokenrail.MCPIRebornServer.desktop</launchable>
|
||||||
|
<provides>
|
||||||
|
<id>com.thebrokenrail.MCPIRebornServer.desktop</id>
|
||||||
|
</provides>
|
||||||
|
<project_license>LicenseRef-proprietary</project_license>
|
||||||
|
<developer_name>TheBrokenRail & Mojang AB</developer_name>
|
||||||
|
<content_rating type="oars-1.0">
|
||||||
|
<content_attribute id="violence-cartoon">moderate</content_attribute>
|
||||||
|
<content_attribute id="violence-fantasy">none</content_attribute>
|
||||||
|
<content_attribute id="violence-realistic">none</content_attribute>
|
||||||
|
<content_attribute id="violence-bloodshed">none</content_attribute>
|
||||||
|
<content_attribute id="violence-sexual">none</content_attribute>
|
||||||
|
<content_attribute id="drugs-alcohol">none</content_attribute>
|
||||||
|
<content_attribute id="drugs-narcotics">none</content_attribute>
|
||||||
|
<content_attribute id="drugs-tobacco">none</content_attribute>
|
||||||
|
<content_attribute id="sex-nudity">none</content_attribute>
|
||||||
|
<content_attribute id="sex-themes">none</content_attribute>
|
||||||
|
<content_attribute id="language-profanity">none</content_attribute>
|
||||||
|
<content_attribute id="language-humor">none</content_attribute>
|
||||||
|
<content_attribute id="language-discrimination">none</content_attribute>
|
||||||
|
<content_attribute id="social-chat">intense</content_attribute>
|
||||||
|
<content_attribute id="social-info">none</content_attribute>
|
||||||
|
<content_attribute id="social-audio">none</content_attribute>
|
||||||
|
<content_attribute id="social-location">none</content_attribute>
|
||||||
|
<content_attribute id="social-contacts">none</content_attribute>
|
||||||
|
<content_attribute id="money-purchasing">none</content_attribute>
|
||||||
|
<content_attribute id="money-gambling">none</content_attribute>
|
||||||
|
</content_rating>
|
||||||
|
</component>
|
||||||
|
|
|
@ -1,173 +1,181 @@
|
||||||
#define _FILE_OFFSET_BITS 64
|
#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 <libreborn/libreborn.h>
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
#include "bootstrap.h"
|
#include "bootstrap.h"
|
||||||
#include "patchelf.h"
|
#include "patchelf.h"
|
||||||
#include "crash-report.h"
|
|
||||||
|
// Set Environmental Variable
|
||||||
|
#define PRESERVE_ENVIRONMENTAL_VARIABLE(name) \
|
||||||
|
{ \
|
||||||
|
char *original_env_value = getenv(name); \
|
||||||
|
if (original_env_value != NULL) { \
|
||||||
|
setenv("ORIGINAL_" name, original_env_value, 1); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
static void trim(char **value) {
|
||||||
|
// Remove Trailing Colon
|
||||||
|
int length = strlen(*value);
|
||||||
|
if ((*value)[length - 1] == ':') {
|
||||||
|
(*value)[length - 1] = '\0';
|
||||||
|
}
|
||||||
|
if ((*value)[0] == ':') {
|
||||||
|
*value = &(*value)[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void set_and_print_env(const char *name, char *value) {
|
||||||
|
// Set Variable With No Trailing Colon
|
||||||
|
static const char *unmodified_name_prefix = "MCPI_";
|
||||||
|
if (!starts_with(name, unmodified_name_prefix)) {
|
||||||
|
trim(&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print New Value
|
||||||
|
DEBUG("Set %s = %s", name, value);
|
||||||
|
|
||||||
|
// Set The Value
|
||||||
|
setenv(name, value, 1);
|
||||||
|
}
|
||||||
|
#ifndef __ARM_ARCH
|
||||||
|
#define PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU(name) \
|
||||||
|
{ \
|
||||||
|
char *old_value = getenv("QEMU_SET_ENV"); \
|
||||||
|
char *new_value = NULL; \
|
||||||
|
/* Pass Variable */ \
|
||||||
|
safe_asprintf(&new_value, "%s%s%s=%s", old_value == NULL ? "" : old_value, old_value == NULL ? "" : ",", name, getenv(name)); \
|
||||||
|
setenv("QEMU_SET_ENV", new_value, 1); \
|
||||||
|
free(new_value); \
|
||||||
|
/* Reset Variable */ \
|
||||||
|
RESET_ENVIRONMENTAL_VARIABLE(name); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get Environmental Variable
|
||||||
|
static char *get_env_safe(const char *name) {
|
||||||
|
// Get Variable Or Blank String If Not Set
|
||||||
|
char *ret = getenv(name);
|
||||||
|
return ret != NULL ? ret : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 Executable
|
||||||
|
int result = access(name, R_OK);
|
||||||
|
if (result == 0) {
|
||||||
|
// Add To LD_PRELOAD
|
||||||
|
string_append(ld_preload, ":%s", name);
|
||||||
|
} else if (result == -1 && errno != 0) {
|
||||||
|
// Fail
|
||||||
|
INFO("Unable To Acesss: %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 MCPI_BINARY "minecraft-pi"
|
||||||
#define QEMU_BINARY "qemu-arm"
|
#define QEMU_BINARY "qemu-arm"
|
||||||
|
|
||||||
#define REQUIRED_PAGE_SIZE 4096
|
|
||||||
#define _STR(x) #x
|
|
||||||
#define STR(x) _STR(x)
|
|
||||||
|
|
||||||
// Exit Handler
|
|
||||||
static void exit_handler(__attribute__((unused)) int signal_id) {
|
|
||||||
// Pass Signal To Child
|
|
||||||
murder_children();
|
|
||||||
while (wait(NULL) > 0) {}
|
|
||||||
_exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug Information
|
|
||||||
static void run_debug_command(const char *const command[], const char *prefix) {
|
|
||||||
int status = 0;
|
|
||||||
char *output = run_command(command, &status, NULL);
|
|
||||||
if (output != NULL) {
|
|
||||||
// Remove Newline
|
|
||||||
size_t length = strlen(output);
|
|
||||||
if (length > 0 && output[length - 1] == '\n') {
|
|
||||||
output[length - 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print
|
|
||||||
DEBUG("%s: %s", prefix, output);
|
|
||||||
free(output);
|
|
||||||
}
|
|
||||||
if (!is_exit_status_success(status)) {
|
|
||||||
ERR("Unable To Gather Debug Information");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void print_debug_information() {
|
|
||||||
// System Information
|
|
||||||
const char *const command[] = {"uname", "-a", NULL};
|
|
||||||
run_debug_command(command, "System Information");
|
|
||||||
|
|
||||||
// Version
|
|
||||||
DEBUG("Reborn Version: v%s", MCPI_VERSION);
|
|
||||||
|
|
||||||
// Architecture
|
|
||||||
const char *arch = "Unknown";
|
|
||||||
#ifdef __x86_64__
|
|
||||||
arch = "AMD64";
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
arch = "ARM64";
|
|
||||||
#elif defined(__arm__)
|
|
||||||
arch = "ARM32";
|
|
||||||
#endif
|
|
||||||
DEBUG("Reborn Target Architecture: %s", arch);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pre-Bootstrap
|
// Pre-Bootstrap
|
||||||
void pre_bootstrap(int argc, char *argv[]) {
|
void pre_bootstrap() {
|
||||||
// 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 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
|
// GTK Dark Mode
|
||||||
#ifndef MCPI_SERVER_MODE
|
#ifndef MCPI_HEADLESS_MODE
|
||||||
set_and_print_env("GTK_THEME", "Adwaita:dark");
|
set_and_print_env("GTK_THEME", "Adwaita:dark");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Get Binary Directory
|
||||||
|
char *binary_directory = get_binary_directory();
|
||||||
|
|
||||||
// Configure PATH
|
// Configure PATH
|
||||||
{
|
{
|
||||||
// Get Binary Directory
|
|
||||||
char *binary_directory = get_binary_directory();
|
|
||||||
|
|
||||||
// Add Library Directory
|
// Add Library Directory
|
||||||
char *new_path = NULL;
|
char *new_path;
|
||||||
safe_asprintf(&new_path, "%s/bin", binary_directory);
|
safe_asprintf(&new_path, "%s/bin", binary_directory);
|
||||||
// Add Existing PATH
|
// Add Existing PATH
|
||||||
{
|
{
|
||||||
char *value = getenv("PATH");
|
char *value = get_env_safe("PATH");
|
||||||
if (value != NULL && strlen(value) > 0) {
|
if (strlen(value) > 0) {
|
||||||
string_append(&new_path, ":%s", value);
|
string_append(&new_path, ":%s", value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set And Free
|
// Set And Free
|
||||||
set_and_print_env("PATH", new_path);
|
set_and_print_env("PATH", new_path);
|
||||||
free(new_path);
|
free(new_path);
|
||||||
|
|
||||||
// Free Binary Directory
|
|
||||||
free(binary_directory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --copy-sdk
|
// Free Binary Directory
|
||||||
for (int i = 1; i < argc; i++) {
|
free(binary_directory);
|
||||||
if (strcmp(argv[i], "--copy-sdk") == 0) {
|
|
||||||
char *binary_directory = get_binary_directory();
|
|
||||||
copy_sdk(binary_directory, 0);
|
|
||||||
free(binary_directory);
|
|
||||||
fflush(stdout);
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Crash Reports
|
|
||||||
setup_crash_report();
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Check Page Size (Not Needed When Using QEMU)
|
|
||||||
#ifndef MCPI_USE_QEMU
|
|
||||||
long page_size = sysconf(_SC_PAGESIZE);
|
|
||||||
if (page_size != REQUIRED_PAGE_SIZE) {
|
|
||||||
ERR("Invalid page size! A page size of %ld bytes is required, but the system size is %ld bytes.", (long) REQUIRED_PAGE_SIZE, page_size);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Debug Information
|
|
||||||
print_debug_information();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bootstrap
|
// Bootstrap
|
||||||
|
@ -176,23 +184,17 @@ void bootstrap(int argc, char *argv[]) {
|
||||||
|
|
||||||
// Get Binary Directory
|
// Get Binary Directory
|
||||||
char *binary_directory = get_binary_directory();
|
char *binary_directory = get_binary_directory();
|
||||||
DEBUG("Binary Directory: %s", binary_directory);
|
|
||||||
|
|
||||||
// Copy SDK
|
// Handle AppImage
|
||||||
copy_sdk(binary_directory, 1);
|
char *usr_prefix = NULL;
|
||||||
|
#ifdef MCPI_IS_APPIMAGE_BUILD
|
||||||
// Set MCPI_REBORN_ASSETS_PATH
|
usr_prefix = getenv("APPDIR");
|
||||||
{
|
#endif
|
||||||
char *assets_path = realpath("/proc/self/exe", NULL);
|
if (usr_prefix == NULL) {
|
||||||
ALLOC_CHECK(assets_path);
|
usr_prefix = "";
|
||||||
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
|
// Resolve Binary Path & Set MCPI_DIRECTORY
|
||||||
char *resolved_path = NULL;
|
|
||||||
{
|
{
|
||||||
// Log
|
// Log
|
||||||
DEBUG("Resolving File Paths...");
|
DEBUG("Resolving File Paths...");
|
||||||
|
@ -200,30 +202,33 @@ void bootstrap(int argc, char *argv[]) {
|
||||||
// Resolve Full Binary Path
|
// Resolve Full Binary Path
|
||||||
char *full_path = NULL;
|
char *full_path = NULL;
|
||||||
safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory);
|
safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory);
|
||||||
resolved_path = realpath(full_path, NULL);
|
char *resolved_path = realpath(full_path, NULL);
|
||||||
ALLOC_CHECK(resolved_path);
|
ALLOC_CHECK(resolved_path);
|
||||||
free(full_path);
|
free(full_path);
|
||||||
|
|
||||||
|
// Set MCPI_EXECUTABLE_PATH
|
||||||
|
set_and_print_env("MCPI_EXECUTABLE_PATH", resolved_path);
|
||||||
|
|
||||||
|
// Set MCPI_DIRECTORY
|
||||||
|
chop_last_component(&resolved_path);
|
||||||
|
set_and_print_env("MCPI_DIRECTORY", resolved_path);
|
||||||
|
free(resolved_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix MCPI Dependencies
|
// Fix MCPI Dependencies
|
||||||
char new_mcpi_exe_path[] = MCPI_PATCHED_DIR "/XXXXXX";
|
|
||||||
{
|
{
|
||||||
// Log
|
// Log
|
||||||
DEBUG("Patching ELF Dependencies...");
|
DEBUG("Patching ELF Dependencies...");
|
||||||
|
|
||||||
// Find Linker
|
// Find Linker
|
||||||
char *linker = NULL;
|
char *linker = NULL;
|
||||||
// Select Linker
|
// Preserve Existing Linker On ARM
|
||||||
#ifdef MCPI_USE_PREBUILT_ARMHF_TOOLCHAIN
|
#ifndef __arm__
|
||||||
// Use ARM Sysroot Linker
|
safe_asprintf(&linker, "%s/usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3", usr_prefix);
|
||||||
safe_asprintf(&linker, "%s/sysroot/lib/ld-linux-armhf.so.3", binary_directory);
|
|
||||||
#else
|
|
||||||
// Use Current Linker
|
|
||||||
linker = patch_get_interpreter();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Patch
|
// Patch
|
||||||
patch_mcpi_elf_dependencies(resolved_path, new_mcpi_exe_path, linker);
|
patch_mcpi_elf_dependencies(linker);
|
||||||
|
|
||||||
// Free Linker Path
|
// Free Linker Path
|
||||||
if (linker != NULL) {
|
if (linker != NULL) {
|
||||||
|
@ -231,86 +236,87 @@ void bootstrap(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
if (!starts_with(new_mcpi_exe_path, MCPI_PATCHED_DIR)) {
|
if (!starts_with(getenv("MCPI_EXECUTABLE_PATH"), "/tmp")) {
|
||||||
IMPOSSIBLE();
|
IMPOSSIBLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set MCPI_VANILLA_ASSETS_PATH
|
// AppImage
|
||||||
{
|
#ifdef MCPI_IS_APPIMAGE_BUILD
|
||||||
char *assets_path = strdup(resolved_path);
|
// Mark Patched MCPI As Part Of AppImage
|
||||||
ALLOC_CHECK(assets_path);
|
set_and_print_env("APPDIR_MODULE_DIR", getenv("MCPI_EXECUTABLE_PATH"));
|
||||||
chop_last_component(&assets_path);
|
#endif
|
||||||
string_append(&assets_path, "/data");
|
|
||||||
set_and_print_env("MCPI_VANILLA_ASSETS_PATH", assets_path);
|
|
||||||
free(assets_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free Resolved Path
|
// Configure LD_LIBRARY_PATH
|
||||||
free(resolved_path);
|
|
||||||
|
|
||||||
// Configure Library Search Path
|
|
||||||
{
|
{
|
||||||
// Log
|
// Log
|
||||||
DEBUG("Setting Linker Search Paths...");
|
DEBUG("Setting Linker Search Paths...");
|
||||||
|
|
||||||
// Prepare
|
// Preserve
|
||||||
char *transitive_ld_path = NULL;
|
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH");
|
||||||
char *mcpi_ld_path = NULL;
|
char *new_ld_path = NULL;
|
||||||
|
|
||||||
// Library Search Path For Native Components
|
// Add Library Directory
|
||||||
|
safe_asprintf(&new_ld_path, "%s/lib", binary_directory);
|
||||||
|
|
||||||
|
// Load ARM Libraries (Ensure Priority)
|
||||||
|
string_append(&new_ld_path, ":%s/usr/lib/arm-linux-gnueabihf:%s/usr/arm-linux-gnueabihf/lib", usr_prefix, usr_prefix);
|
||||||
|
|
||||||
|
// Add LD_LIBRARY_PATH
|
||||||
{
|
{
|
||||||
// Add Native Library Directory
|
char *value = get_env_safe("LD_LIBRARY_PATH");
|
||||||
safe_asprintf(&transitive_ld_path, "%s/lib/native", binary_directory);
|
if (strlen(value) > 0) {
|
||||||
|
string_append(&new_ld_path, ":%s", value);
|
||||||
// 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
|
// Set And Free
|
||||||
{
|
set_and_print_env("LD_LIBRARY_PATH", new_ld_path);
|
||||||
// Add ARM Library Directory
|
free(new_ld_path);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure Preloaded Objects
|
// Configure LD_PRELOAD
|
||||||
{
|
{
|
||||||
// Log
|
// Log
|
||||||
DEBUG("Locating Mods...");
|
DEBUG("Locating Mods...");
|
||||||
|
|
||||||
// Native Components
|
// Preserve
|
||||||
char *host_ld_preload = getenv("LD_PRELOAD");
|
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_PRELOAD");
|
||||||
set_and_print_env("MCPI_NATIVE_LD_PRELOAD", host_ld_preload);
|
char *new_ld_preload = NULL;
|
||||||
|
|
||||||
// ARM Components
|
// Built-In Mods
|
||||||
bootstrap_mods(binary_directory);
|
{
|
||||||
|
// Get Mods Folder
|
||||||
|
char *mods_folder = NULL;
|
||||||
|
safe_asprintf(&mods_folder, "%s/mods/", binary_directory);
|
||||||
|
// Load Mods From ./mods
|
||||||
|
load(&new_ld_preload, mods_folder);
|
||||||
|
// Free Mods Folder
|
||||||
|
free(mods_folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~/.minecraft-pi/mods
|
||||||
|
{
|
||||||
|
// Get Mods Folder
|
||||||
|
char *mods_folder = NULL;
|
||||||
|
safe_asprintf(&mods_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA "/mods/", getenv("HOME"));
|
||||||
|
// Load Mods From ./mods
|
||||||
|
load(&new_ld_preload, mods_folder);
|
||||||
|
// Free Mods Folder
|
||||||
|
free(mods_folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add LD_PRELOAD
|
||||||
|
{
|
||||||
|
char *value = get_env_safe("LD_PRELOAD");
|
||||||
|
if (strlen(value) > 0) {
|
||||||
|
string_append(&new_ld_preload, ":%s", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set LD_PRELOAD
|
||||||
|
set_and_print_env("LD_PRELOAD", new_ld_preload);
|
||||||
|
free(new_ld_preload);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free Binary Directory
|
// Free Binary Directory
|
||||||
|
@ -331,28 +337,16 @@ void bootstrap(int argc, char *argv[]) {
|
||||||
new_args[argv_start + argc] = NULL;
|
new_args[argv_start + argc] = NULL;
|
||||||
|
|
||||||
// Set Executable Argument
|
// Set Executable Argument
|
||||||
new_args[argv_start] = new_mcpi_exe_path;
|
new_args[argv_start] = getenv("MCPI_EXECUTABLE_PATH");
|
||||||
|
|
||||||
// Non-ARM Systems Need QEMU
|
// Non-ARM Systems Need QEMU
|
||||||
#ifdef MCPI_USE_QEMU
|
#ifndef __ARM_ARCH
|
||||||
argv_start--;
|
argv_start--;
|
||||||
new_args[argv_start] = QEMU_BINARY;
|
new_args[argv_start] = QEMU_BINARY;
|
||||||
// Use 4k Page Size
|
|
||||||
set_and_print_env("QEMU_PAGESIZE", STR(REQUIRED_PAGE_SIZE));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup Environment
|
// Prevent QEMU From Being Modded
|
||||||
setup_exec_environment(1);
|
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_LIBRARY_PATH");
|
||||||
|
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_PRELOAD");
|
||||||
// Pass LD_* Variables Through QEMU
|
|
||||||
#ifdef MCPI_USE_QEMU
|
|
||||||
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
|
#endif
|
||||||
|
|
||||||
// Run
|
// Run
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void pre_bootstrap(int argc, char *argv[]);
|
void set_and_print_env(const char *name, char *value);
|
||||||
|
|
||||||
|
void pre_bootstrap();
|
||||||
void bootstrap(int argc, char *argv[]);
|
void bootstrap(int argc, char *argv[]);
|
||||||
void copy_sdk(char *binary_directory, int log_with_debug);
|
|
||||||
void bootstrap_mods(char *binary_directory);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
FALSE Full Touch GUI
|
|
||||||
TRUE Fix Bow & Arrow
|
|
||||||
TRUE Fix Attacking
|
|
||||||
FALSE Force Mob Spawning
|
|
||||||
TRUE Disable Autojump By Default
|
|
||||||
TRUE Display Nametags By Default
|
|
||||||
TRUE Fix Sign Placement
|
|
||||||
TRUE Show Block Outlines
|
|
||||||
FALSE Expand Creative Mode Inventory
|
|
||||||
FALSE Remove Creative Mode Restrictions
|
|
||||||
FALSE Display Slot Count In Creative Mode
|
|
||||||
FALSE Force Survival Mode Inventory UI
|
|
||||||
FALSE Force Survival Mode Inventory Behavior
|
|
||||||
FALSE Maximize Creative Mode Inventory Stack Size
|
|
||||||
TRUE Animated Water
|
|
||||||
TRUE Animated Lava
|
|
||||||
TRUE Animated Fire
|
|
||||||
TRUE Remove Invalid Item Background
|
|
||||||
TRUE Disable "gui_blocks" Atlas
|
|
||||||
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
|
|
||||||
TRUE Improved Cursor Rendering
|
|
||||||
TRUE Disable V-Sync
|
|
||||||
TRUE Fix Options Screen
|
|
||||||
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
|
|
||||||
FALSE Disable Speed Bridging
|
|
||||||
FALSE Disable Creative Mode Mining Delay
|
|
||||||
FALSE Add Biome Colors To Grass
|
|
||||||
TRUE Generate Caves
|
|
||||||
FALSE Disable Block Tinting
|
|
||||||
TRUE Disable Hostile AI In Creative Mode
|
|
||||||
TRUE Load Custom Skins
|
|
||||||
TRUE 3D Chest Model
|
|
||||||
TRUE Replace Block Highlight With Outline
|
|
||||||
TRUE Add Cake
|
|
||||||
TRUE Use Java Beta 1.3 Light Ramp
|
|
||||||
TRUE Send Full Level When Hosting Game
|
|
||||||
FALSE Food Overlay
|
|
||||||
TRUE Add Splashes
|
|
||||||
TRUE Display Date In Select World Screen
|
|
||||||
TRUE Optimized Chunk Sorting
|
|
||||||
TRUE Disable Buggy Held Item Caching
|
|
||||||
TRUE Add Reborn Info To Options
|
|
||||||
FALSE Track FPS
|
|
|
@ -1,171 +0,0 @@
|
||||||
#include <cstdlib>
|
|
||||||
#include <string>
|
|
||||||
#include <fstream>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <sstream>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "launcher.h"
|
|
||||||
#include "cache.h"
|
|
||||||
|
|
||||||
// Get Cache Path
|
|
||||||
static std::string get_cache_path() {
|
|
||||||
const char *home = getenv("HOME");
|
|
||||||
if (home == nullptr) {
|
|
||||||
IMPOSSIBLE();
|
|
||||||
}
|
|
||||||
return std::string(home) + HOME_SUBDIRECTORY_FOR_GAME_DATA "/.launcher-cache";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load
|
|
||||||
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
|
|
||||||
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 (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());
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save
|
|
||||||
#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); \
|
|
||||||
}
|
|
||||||
void save_cache() {
|
|
||||||
// Log
|
|
||||||
DEBUG("Saving Launcher Cache...");
|
|
||||||
|
|
||||||
// Open File
|
|
||||||
std::ofstream stream(get_cache_path(), std::ios::out | std::ios::binary);
|
|
||||||
if (!stream) {
|
|
||||||
// Fail
|
|
||||||
WARN("Unable To Open Launcher Cache For Saving");
|
|
||||||
} else {
|
|
||||||
// Lock File
|
|
||||||
int lock_fd = lock_file(get_cache_path().c_str());
|
|
||||||
|
|
||||||
// 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.good()) {
|
|
||||||
WARN("Failure While Saving Launcher Cache");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unlock File
|
|
||||||
unlock_file(get_cache_path().c_str(), lock_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wipe Cache
|
|
||||||
void wipe_cache() {
|
|
||||||
// Log
|
|
||||||
INFO("Wiping Launcher Cache...");
|
|
||||||
|
|
||||||
// Unlink File
|
|
||||||
if (unlink(get_cache_path().c_str()) != 0) {
|
|
||||||
WARN("Failure While Wiping Cache: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
// Cache Version
|
|
||||||
#define CACHE_VERSION 0
|
|
||||||
|
|
||||||
// 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 save_cache();
|
|
||||||
|
|
||||||
// Wipe Cache
|
|
||||||
void wipe_cache();
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <sstream>
|
#include <fstream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
@ -9,13 +9,10 @@
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
#include "../util.h"
|
|
||||||
#include "../bootstrap.h"
|
#include "../bootstrap.h"
|
||||||
#include "launcher.h"
|
|
||||||
#include "cache.h"
|
|
||||||
|
|
||||||
// Strip Feature Flag Default
|
// Strip Feature Flag Default
|
||||||
std::string strip_feature_flag_default(std::string flag, bool *default_ret) {
|
static std::string strip_feature_flag_default(std::string flag, bool *default_ret) {
|
||||||
// Valid Values
|
// Valid Values
|
||||||
std::string true_str = "TRUE ";
|
std::string true_str = "TRUE ";
|
||||||
std::string false_str = "FALSE ";
|
std::string false_str = "FALSE ";
|
||||||
|
@ -39,44 +36,46 @@ std::string strip_feature_flag_default(std::string flag, bool *default_ret) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load Available Feature Flags
|
// Load Available Feature Flags
|
||||||
extern unsigned char available_feature_flags[];
|
static void load_available_feature_flags(std::function<void(std::string)> callback) {
|
||||||
extern size_t available_feature_flags_len;
|
|
||||||
void load_available_feature_flags(std::function<void(std::string)> callback) {
|
|
||||||
// Get Path
|
// Get Path
|
||||||
char *binary_directory = get_binary_directory();
|
char *binary_directory = get_binary_directory();
|
||||||
std::string path = std::string(binary_directory) + "/available-feature-flags";
|
std::string path = std::string(binary_directory) + "/available-feature-flags";
|
||||||
free(binary_directory);
|
free(binary_directory);
|
||||||
// Load File
|
// Load File
|
||||||
std::string data(available_feature_flags, available_feature_flags + available_feature_flags_len);
|
std::ifstream stream(path);
|
||||||
std::stringstream stream(data);
|
if (stream && stream.good()) {
|
||||||
// Store Lines
|
std::vector<std::string> lines;
|
||||||
std::vector<std::string> lines;
|
// Read File
|
||||||
// Read File
|
{
|
||||||
{
|
std::string line;
|
||||||
std::string line;
|
while (std::getline(stream, line)) {
|
||||||
while (std::getline(stream, line)) {
|
if (line.length() > 0) {
|
||||||
if (line.length() > 0) {
|
// Verify Line
|
||||||
// Verify Line
|
if (line.find('|') == std::string::npos) {
|
||||||
if (line.find('|') == std::string::npos) {
|
lines.push_back(line);
|
||||||
lines.push_back(line);
|
} else {
|
||||||
} else {
|
// Invalid Line
|
||||||
// Invalid Line
|
ERR("Feature Flag Contains Invalid '|'");
|
||||||
ERR("Feature Flag Contains Invalid '|'");
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Sort
|
|
||||||
std::sort(lines.begin(), lines.end(), [](std::string a, std::string b) {
|
|
||||||
// Strip Defaults
|
|
||||||
std::string stripped_a = strip_feature_flag_default(a, NULL);
|
|
||||||
std::string stripped_b = strip_feature_flag_default(b, NULL);
|
|
||||||
// Sort
|
// Sort
|
||||||
return stripped_a < stripped_b;
|
std::sort(lines.begin(), lines.end(), [](std::string a, std::string b) {
|
||||||
});
|
// Strip Defaults
|
||||||
// Run Callbacks
|
std::string stripped_a = strip_feature_flag_default(a, NULL);
|
||||||
for (std::string &line : lines) {
|
std::string stripped_b = strip_feature_flag_default(b, NULL);
|
||||||
callback(line);
|
// Sort
|
||||||
|
return stripped_a < stripped_b;
|
||||||
|
});
|
||||||
|
// Run Callbacks
|
||||||
|
for (std::string line : lines) {
|
||||||
|
callback(line);
|
||||||
|
}
|
||||||
|
// Close File
|
||||||
|
stream.close();
|
||||||
|
} else {
|
||||||
|
ERR("Unable To Load Available Feature Flags");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +85,7 @@ static void run_command_and_set_env(const char *env_name, const char *command[])
|
||||||
if (getenv(env_name) == NULL) {
|
if (getenv(env_name) == NULL) {
|
||||||
// Run
|
// Run
|
||||||
int return_code;
|
int return_code;
|
||||||
char *output = run_command(command, &return_code, NULL);
|
char *output = run_command(command, &return_code);
|
||||||
if (output != NULL) {
|
if (output != NULL) {
|
||||||
// Trim
|
// Trim
|
||||||
int length = strlen(output);
|
int length = strlen(output);
|
||||||
|
@ -99,23 +98,19 @@ static void run_command_and_set_env(const char *env_name, const char *command[])
|
||||||
free(output);
|
free(output);
|
||||||
}
|
}
|
||||||
// Check Return Code
|
// Check Return Code
|
||||||
if (!is_exit_status_success(return_code)) {
|
if (return_code != 0) {
|
||||||
// Launch Interrupted
|
ERR("Launch Interrupted");
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use Zenity To Set Environmental Variable
|
// Use Zenity To Set Environmental Variable
|
||||||
#define DIALOG_TITLE "Launcher"
|
|
||||||
static void run_zenity_and_set_env(const char *env_name, std::vector<std::string> command) {
|
static void run_zenity_and_set_env(const char *env_name, std::vector<std::string> command) {
|
||||||
// Create Full Command
|
// Create Full Command
|
||||||
std::vector<std::string> full_command;
|
std::vector<std::string> full_command;
|
||||||
full_command.push_back("zenity");
|
full_command.push_back("zenity");
|
||||||
full_command.push_back("--title");
|
full_command.push_back("--class");
|
||||||
full_command.push_back(DIALOG_TITLE);
|
full_command.push_back(GUI_TITLE);
|
||||||
full_command.push_back("--name");
|
|
||||||
full_command.push_back(MCPI_APP_ID);
|
|
||||||
full_command.insert(full_command.end(), command.begin(), command.end());
|
full_command.insert(full_command.end(), command.begin(), command.end());
|
||||||
// Convert To C Array
|
// Convert To C Array
|
||||||
const char *full_command_array[full_command.size() + 1];
|
const char *full_command_array[full_command.size() + 1];
|
||||||
|
@ -127,35 +122,10 @@ static void run_zenity_and_set_env(const char *env_name, std::vector<std::string
|
||||||
run_command_and_set_env(env_name, full_command_array);
|
run_command_and_set_env(env_name, full_command_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Variable If Not Already Set
|
|
||||||
static void set_env_if_unset(const char *env_name, std::function<std::string()> callback) {
|
|
||||||
if (getenv(env_name) == NULL) {
|
|
||||||
char *value = strdup(callback().c_str());
|
|
||||||
ALLOC_CHECK(value);
|
|
||||||
set_and_print_env(env_name, value);
|
|
||||||
free(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Launch
|
// Launch
|
||||||
#define LIST_DIALOG_SIZE "400"
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
// Don't Run As Root
|
// Pre-Bootstrap
|
||||||
if (getenv("_MCPI_SKIP_ROOT_CHECK") == NULL && (getuid() == 0 || geteuid() == 0)) {
|
pre_bootstrap();
|
||||||
ERR("Don't Run As Root");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure HOME
|
|
||||||
if (getenv("HOME") == NULL) {
|
|
||||||
ERR("$HOME Isn't Set");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check For Display
|
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
|
||||||
if (getenv("DISPLAY") == NULL && getenv("WAYLAND_DISPLAY") == NULL) {
|
|
||||||
ERR("No display attached! Make sure $DISPLAY or $WAYLAND_DISPLAY is set.");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Print Features
|
// Print Features
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
|
@ -169,70 +139,24 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-Bootstrap
|
|
||||||
pre_bootstrap(argc, argv);
|
|
||||||
|
|
||||||
// Create ~/.minecraft-pi If Needed
|
// Create ~/.minecraft-pi If Needed
|
||||||
|
// Minecraft Folder
|
||||||
{
|
{
|
||||||
char *minecraft_folder = NULL;
|
char *minecraft_folder = NULL;
|
||||||
safe_asprintf(&minecraft_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA, getenv("HOME"));
|
safe_asprintf(&minecraft_folder, "%s/.minecraft-pi", getenv("HOME"));
|
||||||
const char *const command[] = {"mkdir", "-p", minecraft_folder, NULL};
|
{
|
||||||
run_simple_command(command, "Unable To Create Data Directory");
|
// Check Minecraft Folder
|
||||||
free(minecraft_folder);
|
struct stat obj;
|
||||||
}
|
if (stat(minecraft_folder, &obj) != 0 || !S_ISDIR(obj.st_mode)) {
|
||||||
|
// Create Minecraft Folder
|
||||||
// --wipe-cache
|
int ret = mkdir(minecraft_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||||
for (int i = 1; i < argc; i++) {
|
if (ret != 0) {
|
||||||
if (strcmp(argv[i], "--wipe-cache") == 0) {
|
// Unable To Create Folder
|
||||||
wipe_cache();
|
ERR("Error Creating Directory: %s: %s", minecraft_folder, strerror(errno));
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --no-cache
|
|
||||||
bool no_cache = false;
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
if (strcmp(argv[i], "--no-cache") == 0) {
|
|
||||||
no_cache = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Load Cache
|
|
||||||
launcher_cache cache = no_cache ? empty_cache : load_cache();
|
|
||||||
|
|
||||||
// --default
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
if (strcmp(argv[i], "--default") == 0) {
|
|
||||||
// Use Default Feature Flags
|
|
||||||
set_env_if_unset("MCPI_FEATURE_FLAGS", [&cache]() {
|
|
||||||
std::string feature_flags = "";
|
|
||||||
load_available_feature_flags([&feature_flags, &cache](std::string flag) {
|
|
||||||
bool value;
|
|
||||||
// Strip Default Value
|
|
||||||
std::string stripped_flag = strip_feature_flag_default(flag, &value);
|
|
||||||
// Use Cache
|
|
||||||
if (cache.feature_flags.count(stripped_flag) > 0) {
|
|
||||||
value = cache.feature_flags[stripped_flag];
|
|
||||||
}
|
|
||||||
// Specify Default Value
|
|
||||||
if (value) {
|
|
||||||
// Enabled By Default
|
|
||||||
feature_flags += stripped_flag + '|';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (feature_flags.length() > 0 && feature_flags[feature_flags.length() - 1] == '|') {
|
|
||||||
feature_flags.pop_back();
|
|
||||||
}
|
}
|
||||||
return feature_flags;
|
}
|
||||||
});
|
|
||||||
set_env_if_unset("MCPI_RENDER_DISTANCE", [&cache]() {
|
|
||||||
return cache.render_distance;
|
|
||||||
});
|
|
||||||
set_env_if_unset("MCPI_USERNAME", [&cache]() {
|
|
||||||
return cache.username;
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
free(minecraft_folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup MCPI_FEATURE_FLAGS
|
// Setup MCPI_FEATURE_FLAGS
|
||||||
|
@ -241,23 +165,19 @@ int main(int argc, char *argv[]) {
|
||||||
command.push_back("--list");
|
command.push_back("--list");
|
||||||
command.push_back("--checklist");
|
command.push_back("--checklist");
|
||||||
command.push_back("--width");
|
command.push_back("--width");
|
||||||
command.push_back(LIST_DIALOG_SIZE);
|
command.push_back("400");
|
||||||
command.push_back("--height");
|
command.push_back("--height");
|
||||||
command.push_back(LIST_DIALOG_SIZE);
|
command.push_back("400");
|
||||||
command.push_back("--column");
|
command.push_back("--column");
|
||||||
command.push_back("Enabled");
|
command.push_back("Enabled");
|
||||||
command.push_back("--column");
|
command.push_back("--column");
|
||||||
command.push_back("Feature");
|
command.push_back("Feature");
|
||||||
load_available_feature_flags([&command, &cache](std::string flag) {
|
load_available_feature_flags([&command](std::string flag) {
|
||||||
bool value;
|
bool default_value;
|
||||||
// Strip Default Value
|
// Strip Default Value
|
||||||
std::string stripped_flag = strip_feature_flag_default(flag, &value);
|
std::string stripped_flag = strip_feature_flag_default(flag, &default_value);
|
||||||
// Use Cache
|
|
||||||
if (cache.feature_flags.count(stripped_flag) > 0) {
|
|
||||||
value = cache.feature_flags[stripped_flag];
|
|
||||||
}
|
|
||||||
// Specify Default Value
|
// Specify Default Value
|
||||||
if (value) {
|
if (default_value) {
|
||||||
// Enabled By Default
|
// Enabled By Default
|
||||||
command.push_back("TRUE");
|
command.push_back("TRUE");
|
||||||
} else {
|
} else {
|
||||||
|
@ -276,20 +196,23 @@ int main(int argc, char *argv[]) {
|
||||||
command.push_back("--list");
|
command.push_back("--list");
|
||||||
command.push_back("--radiolist");
|
command.push_back("--radiolist");
|
||||||
command.push_back("--width");
|
command.push_back("--width");
|
||||||
command.push_back(LIST_DIALOG_SIZE);
|
command.push_back("400");
|
||||||
command.push_back("--height");
|
command.push_back("--height");
|
||||||
command.push_back(LIST_DIALOG_SIZE);
|
command.push_back("400");
|
||||||
command.push_back("--text");
|
command.push_back("--text");
|
||||||
command.push_back("Select Minecraft Render Distance:");
|
command.push_back("Minecraft Render Distance:");
|
||||||
command.push_back("--column");
|
command.push_back("--column");
|
||||||
command.push_back("Selected");
|
command.push_back("Selected");
|
||||||
command.push_back("--column");
|
command.push_back("--column");
|
||||||
command.push_back("Name");
|
command.push_back("Name");
|
||||||
std::string render_distances[] = {"Far", "Normal", "Short", "Tiny"};
|
command.push_back("FALSE");
|
||||||
for (std::string &render_distance : render_distances) {
|
command.push_back("Far");
|
||||||
command.push_back(render_distance.compare(cache.render_distance) == 0 ? "TRUE" : "FALSE");
|
command.push_back("FALSE");
|
||||||
command.push_back(render_distance);
|
command.push_back("Normal");
|
||||||
}
|
command.push_back("TRUE");
|
||||||
|
command.push_back("Short");
|
||||||
|
command.push_back("FALSE");
|
||||||
|
command.push_back("Tiny");
|
||||||
// Run
|
// Run
|
||||||
run_zenity_and_set_env("MCPI_RENDER_DISTANCE", command);
|
run_zenity_and_set_env("MCPI_RENDER_DISTANCE", command);
|
||||||
}
|
}
|
||||||
|
@ -298,18 +221,13 @@ int main(int argc, char *argv[]) {
|
||||||
std::vector<std::string> command;
|
std::vector<std::string> command;
|
||||||
command.push_back("--entry");
|
command.push_back("--entry");
|
||||||
command.push_back("--text");
|
command.push_back("--text");
|
||||||
command.push_back("Enter Minecraft Username:");
|
command.push_back("Minecraft Username:");
|
||||||
command.push_back("--entry-text");
|
command.push_back("--entry-text");
|
||||||
command.push_back(cache.username);
|
command.push_back("StevePi");
|
||||||
// Run
|
// Run
|
||||||
run_zenity_and_set_env("MCPI_USERNAME", command);
|
run_zenity_and_set_env("MCPI_USERNAME", command);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save Cache
|
|
||||||
if (!no_cache) {
|
|
||||||
save_cache();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bootstrap
|
// Bootstrap
|
||||||
bootstrap(argc, argv);
|
bootstrap(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
// Defaults
|
|
||||||
#define DEFAULT_USERNAME "StevePi"
|
|
||||||
#define DEFAULT_RENDER_DISTANCE "Short"
|
|
||||||
|
|
||||||
// Feature Flags
|
|
||||||
std::string strip_feature_flag_default(std::string flag, bool *default_ret);
|
|
||||||
void load_available_feature_flags(std::function<void(std::string)> callback);
|
|
|
@ -1,260 +0,0 @@
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <poll.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "crash-report.h"
|
|
||||||
|
|
||||||
// Show Crash Report Dialog
|
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
|
||||||
#define DIALOG_TITLE "Crash Report"
|
|
||||||
#define CRASH_REPORT_DIALOG_WIDTH "640"
|
|
||||||
#define CRASH_REPORT_DIALOG_HEIGHT "480"
|
|
||||||
static void show_report(const char *log_filename) {
|
|
||||||
// Fork
|
|
||||||
pid_t pid = fork();
|
|
||||||
if (pid == 0) {
|
|
||||||
// Child
|
|
||||||
setsid();
|
|
||||||
ALLOC_CHECK(freopen("/dev/null", "w", stdout));
|
|
||||||
ALLOC_CHECK(freopen("/dev/null", "w", stderr));
|
|
||||||
ALLOC_CHECK(freopen("/dev/null", "r", stdin));
|
|
||||||
const char *command[] = {
|
|
||||||
"zenity",
|
|
||||||
"--title", DIALOG_TITLE,
|
|
||||||
"--name", MCPI_APP_ID,
|
|
||||||
"--width", CRASH_REPORT_DIALOG_WIDTH,
|
|
||||||
"--height", CRASH_REPORT_DIALOG_HEIGHT,
|
|
||||||
"--text-info",
|
|
||||||
"--text", MCPI_APP_BASE_TITLE " has crashed!\n\nNeed help? Consider asking on the <a href=\"https://discord.com/invite/aDqejQGMMy\">Discord server</a>! <i>If you believe this is a problem with " MCPI_APP_BASE_TITLE " itself, please upload this crash report to the #bugs Discord channel.</i>",
|
|
||||||
"--filename", log_filename,
|
|
||||||
"--no-wrap",
|
|
||||||
"--font", "Monospace",
|
|
||||||
"--save-filename", MCPI_VARIANT_NAME "-crash-report.log",
|
|
||||||
"--ok-label", "Exit",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
safe_execvpe(command, (const char *const *) environ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Exit Handler
|
|
||||||
static void exit_handler(__attribute__((unused)) int signal) {
|
|
||||||
// Murder
|
|
||||||
murder_children();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup
|
|
||||||
#define PIPE_READ 0
|
|
||||||
#define PIPE_WRITE 1
|
|
||||||
#define MCPI_LOGS_DIR "/tmp/.minecraft-pi-logs"
|
|
||||||
static char log_filename[] = MCPI_LOGS_DIR "/XXXXXX";
|
|
||||||
static int log_file_fd = -1;
|
|
||||||
void setup_log_file() {
|
|
||||||
// Ensure Temporary Directory
|
|
||||||
{
|
|
||||||
// Check If It Exists
|
|
||||||
struct stat tmp_stat;
|
|
||||||
int exists = stat(MCPI_LOGS_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode);
|
|
||||||
if (!exists) {
|
|
||||||
// Doesn't Exist
|
|
||||||
if (mkdir(MCPI_LOGS_DIR, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
|
|
||||||
ERR("Unable To Create Temporary Folder: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create Temporary File
|
|
||||||
log_file_fd = mkstemp(log_filename);
|
|
||||||
if (log_file_fd == -1) {
|
|
||||||
ERR("Unable To Create Log File: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Environment
|
|
||||||
char *log_file_fd_env = NULL;
|
|
||||||
safe_asprintf(&log_file_fd_env, "%i", log_file_fd);
|
|
||||||
set_and_print_env("MCPI_LOG_FILE_FD", log_file_fd_env);
|
|
||||||
free(log_file_fd_env);
|
|
||||||
}
|
|
||||||
void setup_crash_report() {
|
|
||||||
// Store Output
|
|
||||||
int output_pipe[2];
|
|
||||||
safe_pipe2(output_pipe, 0);
|
|
||||||
int error_pipe[2];
|
|
||||||
safe_pipe2(error_pipe, 0);
|
|
||||||
int input_pipe[2];
|
|
||||||
safe_pipe2(input_pipe, 0);
|
|
||||||
|
|
||||||
// Fork
|
|
||||||
pid_t ret = fork();
|
|
||||||
if (ret == -1) {
|
|
||||||
ERR("Unable To Fork: %s", strerror(errno));
|
|
||||||
} else if (ret == 0) {
|
|
||||||
// Child Process
|
|
||||||
|
|
||||||
// Pipe stdio
|
|
||||||
dup2(output_pipe[PIPE_WRITE], STDOUT_FILENO);
|
|
||||||
close(output_pipe[PIPE_READ]);
|
|
||||||
close(output_pipe[PIPE_WRITE]);
|
|
||||||
dup2(error_pipe[PIPE_WRITE], STDERR_FILENO);
|
|
||||||
close(error_pipe[PIPE_READ]);
|
|
||||||
close(error_pipe[PIPE_WRITE]);
|
|
||||||
dup2(input_pipe[PIPE_READ], STDIN_FILENO);
|
|
||||||
close(input_pipe[PIPE_READ]);
|
|
||||||
close(input_pipe[PIPE_WRITE]);
|
|
||||||
|
|
||||||
// Create New Process Group
|
|
||||||
setpgid(0, 0);
|
|
||||||
|
|
||||||
// Continue Execution
|
|
||||||
} else {
|
|
||||||
// Parent Process
|
|
||||||
track_child(ret);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
atexit(murder_children);
|
|
||||||
|
|
||||||
// Close Unneeded File Descriptors
|
|
||||||
close(output_pipe[PIPE_WRITE]);
|
|
||||||
close(error_pipe[PIPE_WRITE]);
|
|
||||||
close(input_pipe[PIPE_READ]);
|
|
||||||
|
|
||||||
// Set Debug Tag
|
|
||||||
reborn_debug_tag = "(Crash Reporter) ";
|
|
||||||
|
|
||||||
// Setup Logging
|
|
||||||
#define BUFFER_SIZE 1024
|
|
||||||
char buf[BUFFER_SIZE];
|
|
||||||
|
|
||||||
// Setup Polling
|
|
||||||
int number_fds = 3;
|
|
||||||
struct pollfd poll_fds[number_fds];
|
|
||||||
poll_fds[0].fd = output_pipe[PIPE_READ];
|
|
||||||
poll_fds[1].fd = error_pipe[PIPE_READ];
|
|
||||||
poll_fds[2].fd = STDIN_FILENO;
|
|
||||||
for (int i = 0; i < number_fds; i++) {
|
|
||||||
poll_fds[i].events = POLLIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poll Data
|
|
||||||
int status;
|
|
||||||
while (waitpid(ret, &status, WNOHANG) != ret) {
|
|
||||||
int poll_ret = poll(poll_fds, number_fds, -1);
|
|
||||||
if (poll_ret == -1) {
|
|
||||||
if (errno == EINTR) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
ERR("Unable To Poll Data: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle Data
|
|
||||||
for (int i = 0; i < number_fds; i++) {
|
|
||||||
if (poll_fds[i].revents != 0) {
|
|
||||||
if (poll_fds[i].revents & POLLIN) {
|
|
||||||
if (poll_fds[i].fd == STDIN_FILENO) {
|
|
||||||
// Data Available From stdin
|
|
||||||
int bytes_available;
|
|
||||||
if (ioctl(fileno(stdin), FIONREAD, &bytes_available) == -1) {
|
|
||||||
bytes_available = 0;
|
|
||||||
}
|
|
||||||
// Read
|
|
||||||
ssize_t bytes_read = read(poll_fds[i].fd, (void *) buf, BUFFER_SIZE);
|
|
||||||
if (bytes_read == -1) {
|
|
||||||
ERR("Unable To Read Log Data: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
// Write To Child
|
|
||||||
if (write(input_pipe[PIPE_WRITE], (void *) buf, bytes_read) == -1) {
|
|
||||||
ERR("Unable To Write Input To Child: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Data Available From Child's stdout/stderr
|
|
||||||
ssize_t bytes_read = read(poll_fds[i].fd, (void *) buf, BUFFER_SIZE - 1 /* Account For NULL-Terminator */);
|
|
||||||
if (bytes_read == -1) {
|
|
||||||
ERR("Unable To Read Log Data: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print To Terminal
|
|
||||||
buf[bytes_read] = '\0';
|
|
||||||
fprintf(poll_fds[i].fd == output_pipe[PIPE_READ] ? stdout : stderr, "%s", buf);
|
|
||||||
|
|
||||||
// Write To log
|
|
||||||
if (write(log_file_fd, (void *) buf, bytes_read) == -1) {
|
|
||||||
ERR("Unable To Write Log Data: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// File Descriptor No Longer Accessible
|
|
||||||
poll_fds[i].events = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Untrack Process
|
|
||||||
untrack_child(ret);
|
|
||||||
|
|
||||||
// Close Pipes
|
|
||||||
close(output_pipe[PIPE_READ]);
|
|
||||||
close(error_pipe[PIPE_READ]);
|
|
||||||
close(input_pipe[PIPE_WRITE]);
|
|
||||||
|
|
||||||
// Check If Is Crash
|
|
||||||
int is_crash = !is_exit_status_success(status);
|
|
||||||
|
|
||||||
// Log Exit Code To log If Crash
|
|
||||||
if (is_crash) {
|
|
||||||
// Create Exit Code Log Line
|
|
||||||
char *exit_status = NULL;
|
|
||||||
get_exit_status_string(status, &exit_status);
|
|
||||||
char *exit_code_line = NULL;
|
|
||||||
safe_asprintf(&exit_code_line, "[CRASH]: Terminated%s\n", exit_status);
|
|
||||||
free(exit_status);
|
|
||||||
|
|
||||||
// Print Exit Code Log Line
|
|
||||||
fprintf(stderr, "%s", exit_code_line);
|
|
||||||
|
|
||||||
// Write Exit Code Log Line
|
|
||||||
if (write(log_file_fd, (void *) exit_code_line, strlen(exit_code_line)) == -1) {
|
|
||||||
ERR("Unable To Write Exit Code To Log: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free Exit Code Log Line
|
|
||||||
free(exit_code_line);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close Log File FD
|
|
||||||
if (close(log_file_fd) == -1) {
|
|
||||||
ERR("Unable To Close Log File Descriptor: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show Crash Log
|
|
||||||
#ifndef MCPI_HEADLESS_MODE
|
|
||||||
if (is_crash) {
|
|
||||||
show_report(log_filename);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Exit
|
|
||||||
exit(WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "bootstrap.h"
|
|
||||||
|
|
||||||
// Get All Mods In Folder
|
|
||||||
static void load(char **ld_preload, const char *folder) {
|
|
||||||
int folder_name_length = strlen(folder);
|
|
||||||
// Open Folder
|
|
||||||
DIR *dp = opendir(folder);
|
|
||||||
if (dp != NULL) {
|
|
||||||
// Loop Through Folder
|
|
||||||
struct dirent *entry = NULL;
|
|
||||||
errno = 0;
|
|
||||||
while (1) {
|
|
||||||
errno = 0;
|
|
||||||
entry = readdir(dp);
|
|
||||||
if (entry != NULL) {
|
|
||||||
// Check If File Is Regular
|
|
||||||
if (entry->d_type == DT_REG) {
|
|
||||||
// Get Full Name
|
|
||||||
int name_length = strlen(entry->d_name);
|
|
||||||
int total_length = folder_name_length + name_length;
|
|
||||||
char name[total_length + 1];
|
|
||||||
|
|
||||||
// Concatenate Folder Name And File Name
|
|
||||||
for (int i = 0; i < folder_name_length; i++) {
|
|
||||||
name[i] = folder[i];
|
|
||||||
}
|
|
||||||
for (int i = 0; i < name_length; i++) {
|
|
||||||
name[folder_name_length + i] = entry->d_name[i];
|
|
||||||
}
|
|
||||||
// Add Terminator
|
|
||||||
name[total_length] = '\0';
|
|
||||||
|
|
||||||
// Check If File Is Accessible
|
|
||||||
int result = access(name, R_OK);
|
|
||||||
if (result == 0) {
|
|
||||||
// Add To LD_PRELOAD
|
|
||||||
string_append(ld_preload, "%s%s", *ld_preload == NULL ? "" : ":", name);
|
|
||||||
} else if (result == -1 && errno != 0) {
|
|
||||||
// Fail
|
|
||||||
WARN("Unable To Access: %s: %s", name, strerror(errno));
|
|
||||||
errno = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (errno != 0) {
|
|
||||||
// Error Reading Contents Of Folder
|
|
||||||
ERR("Error Reading Directory: %s: %s", folder, strerror(errno));
|
|
||||||
} else {
|
|
||||||
// Done!
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Close Folder
|
|
||||||
closedir(dp);
|
|
||||||
} else if (errno == ENOENT) {
|
|
||||||
// Folder Doesn't Exist
|
|
||||||
} else {
|
|
||||||
// Unable To Open Folder
|
|
||||||
ERR("Error Opening Directory: %s: %s", folder, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bootstrap Mods
|
|
||||||
void bootstrap_mods(char *binary_directory) {
|
|
||||||
// Prepare
|
|
||||||
char *preload = NULL;
|
|
||||||
|
|
||||||
// ~/.minecraft-pi/mods
|
|
||||||
{
|
|
||||||
// Get Mods Folder
|
|
||||||
char *mods_folder = NULL;
|
|
||||||
safe_asprintf(&mods_folder, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA "/mods/", getenv("HOME"));
|
|
||||||
// Load Mods From ./mods
|
|
||||||
load(&preload, mods_folder);
|
|
||||||
// Free Mods Folder
|
|
||||||
free(mods_folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Built-In Mods
|
|
||||||
{
|
|
||||||
// Get Mods Folder
|
|
||||||
char *mods_folder = NULL;
|
|
||||||
safe_asprintf(&mods_folder, "%s/mods/", binary_directory);
|
|
||||||
// Load Mods From ./mods
|
|
||||||
load(&preload, mods_folder);
|
|
||||||
// Free Mods Folder
|
|
||||||
free(mods_folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add LD_PRELOAD
|
|
||||||
{
|
|
||||||
char *value = getenv("LD_PRELOAD");
|
|
||||||
if (value != NULL && strlen(value) > 0) {
|
|
||||||
string_append(&preload, ":%s", value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set
|
|
||||||
set_and_print_env("MCPI_ARM_LD_PRELOAD", preload);
|
|
||||||
free(preload);
|
|
||||||
}
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
|
||||||
|
#include "bootstrap.h"
|
||||||
|
#include "patchelf.h"
|
||||||
|
|
||||||
|
// Duplicate MCPI Executable Into /tmp
|
||||||
|
static void duplicate_mcpi_executable() {
|
||||||
|
// Get Original Path
|
||||||
|
const char *original_path = getenv("MCPI_EXECUTABLE_PATH");
|
||||||
|
|
||||||
|
// Generate New File
|
||||||
|
char new_path[] = "/tmp/.minecraft-pi-XXXXXX";
|
||||||
|
int new_file_fd = mkstemp(new_path);
|
||||||
|
if (new_file_fd == -1) {
|
||||||
|
ERR("Unable To Create Temporary File: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
FILE *new_file = fdopen(new_file_fd, "wb");
|
||||||
|
if (new_file == NULL) {
|
||||||
|
ERR("Unable To Open Temporary File: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
set_and_print_env("MCPI_EXECUTABLE_PATH", new_path);
|
||||||
|
|
||||||
|
// Copy Original File
|
||||||
|
{
|
||||||
|
// Open Original File
|
||||||
|
FILE *original_file = fopen(original_path, "rb");
|
||||||
|
if (original_file == NULL) {
|
||||||
|
ERR("Unable To Open File: %s", original_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy
|
||||||
|
#define BUFFER_SIZE 1024
|
||||||
|
char buf[BUFFER_SIZE];
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
while ((bytes_read = fread((void *) buf, 1, BUFFER_SIZE, original_file)) > 0) {
|
||||||
|
fwrite((void *) buf, 1, bytes_read, new_file);
|
||||||
|
if (ferror(new_file) != 0) {
|
||||||
|
ERR("Unable To Write File: %s", new_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ferror(original_file) != 0) {
|
||||||
|
ERR("Unable To Read File: %s", original_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close Original File
|
||||||
|
fclose(original_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close New File
|
||||||
|
fclose(new_file);
|
||||||
|
close(new_file_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix MCPI Dependencies
|
||||||
|
#define patch_mcpi_elf_dependencies_with_extra_patchelf_args(...) \
|
||||||
|
({ \
|
||||||
|
const char *const _macro_command[] = { \
|
||||||
|
"patchelf", \
|
||||||
|
##__VA_ARGS__, \
|
||||||
|
"--remove-needed", "libbcm_host.so", \
|
||||||
|
"--remove-needed", "libX11.so.6", \
|
||||||
|
"--remove-needed", "libEGL.so", \
|
||||||
|
"--replace-needed", "libGLESv2.so", "libGLESv1_CM.so.1", \
|
||||||
|
exe, \
|
||||||
|
NULL \
|
||||||
|
}; \
|
||||||
|
int _macro_return_code = 0; \
|
||||||
|
char *_macro_output = run_command(_macro_command, &_macro_return_code); \
|
||||||
|
if (_macro_output != NULL) { \
|
||||||
|
free(_macro_output); \
|
||||||
|
} \
|
||||||
|
_macro_return_code; \
|
||||||
|
})
|
||||||
|
void patch_mcpi_elf_dependencies(const char *linker) {
|
||||||
|
// Duplicate MCPI executable into /tmp so it can be modified.
|
||||||
|
duplicate_mcpi_executable();
|
||||||
|
|
||||||
|
// Get Path
|
||||||
|
char *exe = getenv("MCPI_EXECUTABLE_PATH");
|
||||||
|
|
||||||
|
// Run patchelf
|
||||||
|
int return_code;
|
||||||
|
if (linker == NULL) {
|
||||||
|
return_code = patch_mcpi_elf_dependencies_with_extra_patchelf_args();
|
||||||
|
} else {
|
||||||
|
return_code = patch_mcpi_elf_dependencies_with_extra_patchelf_args("--set-interpreter", linker);
|
||||||
|
}
|
||||||
|
if (return_code != 0) {
|
||||||
|
ERR("patchelf Failed: Exit Code: %i", return_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix Permissions
|
||||||
|
if (chmod(exe, S_IRUSR | S_IXUSR) != 0) {
|
||||||
|
ERR("Unable To Set File Permissions: %s: %s", exe, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,94 +0,0 @@
|
||||||
#include <cstdlib>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <LIEF/ELF.hpp>
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <link.h>
|
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "patchelf.h"
|
|
||||||
|
|
||||||
// Duplicate MCPI Executable Into /tmp
|
|
||||||
static void duplicate_mcpi_executable(char *new_path) {
|
|
||||||
// Ensure Temporary Directory
|
|
||||||
{
|
|
||||||
// Check If It Exists
|
|
||||||
struct stat tmp_stat;
|
|
||||||
int exists = stat(MCPI_PATCHED_DIR, &tmp_stat) != 0 ? 0 : S_ISDIR(tmp_stat.st_mode);
|
|
||||||
if (!exists) {
|
|
||||||
// Doesn't Exist
|
|
||||||
if (mkdir(MCPI_PATCHED_DIR, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
|
|
||||||
ERR("Unable To Create Temporary Folder: %s", strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate New File
|
|
||||||
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 const char *libraries_to_remove[] = {
|
|
||||||
"libbcm_host.so",
|
|
||||||
"libX11.so.6",
|
|
||||||
"libEGL.so",
|
|
||||||
"libGLESv2.so",
|
|
||||||
"libSDL-1.2.so.0"
|
|
||||||
};
|
|
||||||
static const char *libraries_to_add[] = {
|
|
||||||
"libmedia-layer-core.so"
|
|
||||||
};
|
|
||||||
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, const char *linker) {
|
|
||||||
// Duplicate MCPI executable into /tmp so it can be modified.
|
|
||||||
duplicate_mcpi_executable(new_path);
|
|
||||||
|
|
||||||
// Patch File
|
|
||||||
{
|
|
||||||
std::unique_ptr<LIEF::ELF::Binary> binary = LIEF::ELF::Parser::parse(original_path);
|
|
||||||
if (linker != NULL) {
|
|
||||||
binary->interpreter(linker);
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < (sizeof (libraries_to_remove) / sizeof (const char *)); i++) {
|
|
||||||
binary->remove_library(libraries_to_remove[i]);
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < (sizeof (libraries_to_add) / sizeof (const char *)); i++) {
|
|
||||||
binary->add_library(libraries_to_add[i]);
|
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Interpreter
|
|
||||||
static int dl_iterate_callback(struct dl_phdr_info *info, __attribute__((unused)) size_t size, void *data) {
|
|
||||||
// Only Search Current Program
|
|
||||||
if (strcmp(info->dlpi_name, "") == 0) {
|
|
||||||
for (int i = 0; i < info->dlpi_phnum; i++) {
|
|
||||||
if (info->dlpi_phdr[i].p_type == PT_INTERP) {
|
|
||||||
// Callback
|
|
||||||
*(char **) data = (char *) (info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
char *patch_get_interpreter() {
|
|
||||||
char *interpreter = NULL;
|
|
||||||
dl_iterate_phdr(dl_iterate_callback, &interpreter);
|
|
||||||
if (interpreter != NULL) {
|
|
||||||
interpreter = strdup(interpreter);
|
|
||||||
}
|
|
||||||
return interpreter;
|
|
||||||
}
|
|
|
@ -4,10 +4,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MCPI_PATCHED_DIR "/tmp/.minecraft-pi-patched"
|
void patch_mcpi_elf_dependencies(const char *linker);
|
||||||
|
|
||||||
void patch_mcpi_elf_dependencies(const char *original_path, char *new_path, const char *linker);
|
|
||||||
char *patch_get_interpreter();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "bootstrap.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
// Log
|
|
||||||
#define LOG(is_debug, ...) \
|
|
||||||
{ \
|
|
||||||
if (is_debug) { \
|
|
||||||
DEBUG(__VA_ARGS__); \
|
|
||||||
} else { \
|
|
||||||
INFO(__VA_ARGS__); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy SDK Into ~/.minecraft-pi
|
|
||||||
#define HOME_SUBDIRECTORY_FOR_SDK HOME_SUBDIRECTORY_FOR_GAME_DATA "/sdk"
|
|
||||||
void copy_sdk(char *binary_directory, int log_with_debug) {
|
|
||||||
// Ensure SDK Directory
|
|
||||||
{
|
|
||||||
char *sdk_path = NULL;
|
|
||||||
safe_asprintf(&sdk_path, "%s" HOME_SUBDIRECTORY_FOR_SDK, getenv("HOME"));
|
|
||||||
const char *const command[] = {"mkdir", "-p", sdk_path, NULL};
|
|
||||||
run_simple_command(command, "Unable To Create SDK Directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lock File
|
|
||||||
char *lock_file_path = NULL;
|
|
||||||
safe_asprintf(&lock_file_path, "%s" HOME_SUBDIRECTORY_FOR_SDK "/.lock", getenv("HOME"));
|
|
||||||
int lock_file_fd = lock_file(lock_file_path);
|
|
||||||
|
|
||||||
// Output Directory
|
|
||||||
char *output = NULL;
|
|
||||||
safe_asprintf(&output, "%s" HOME_SUBDIRECTORY_FOR_SDK "/" MCPI_SDK_DIR, getenv("HOME"));
|
|
||||||
// Source Directory
|
|
||||||
char *source = NULL;
|
|
||||||
safe_asprintf(&source, "%s/sdk/.", binary_directory);
|
|
||||||
|
|
||||||
// Clean
|
|
||||||
{
|
|
||||||
const char *const command[] = {"rm", "-rf", output, NULL};
|
|
||||||
run_simple_command(command, "Unable To Clean SDK Output Directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make Directory
|
|
||||||
{
|
|
||||||
const char *const command[] = {"mkdir", "-p", output, NULL};
|
|
||||||
run_simple_command(command, "Unable To Create SDK Output Directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy
|
|
||||||
{
|
|
||||||
const char *const command[] = {"cp", "-ar", source, output, NULL};
|
|
||||||
run_simple_command(command, "Unable To Copy SDK");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log
|
|
||||||
LOG(log_with_debug, "Copied SDK To: %s", output);
|
|
||||||
|
|
||||||
// Free
|
|
||||||
free(output);
|
|
||||||
free(source);
|
|
||||||
|
|
||||||
// Unlock File
|
|
||||||
unlock_file(lock_file_path, lock_file_fd);
|
|
||||||
free(lock_file_path);
|
|
||||||
}
|
|
|
@ -1,13 +1,11 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "../bootstrap.h"
|
#include "../bootstrap.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
// Pre-Bootstrap
|
// Pre-Bootstrap
|
||||||
pre_bootstrap(argc, argv);
|
pre_bootstrap();
|
||||||
|
|
||||||
// Set Home To Current Directory, So World Data Is Stored There
|
// Set Home To Current Directory, So World Data Is Stored There
|
||||||
char *launch_directory = getcwd(NULL, 0);
|
char *launch_directory = getcwd(NULL, 0);
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
#include <libreborn/libreborn.h>
|
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
// Simpler Version Of run_command()
|
|
||||||
void run_simple_command(const char *const command[], const char *error) {
|
|
||||||
int status = 0;
|
|
||||||
char *output = run_command(command, &status, NULL);
|
|
||||||
if (output != NULL) {
|
|
||||||
free(output);
|
|
||||||
}
|
|
||||||
if (!is_exit_status_success(status)) {
|
|
||||||
ERR("%s", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chop Off Last Component
|
|
||||||
void chop_last_component(char **str) {
|
|
||||||
size_t length = strlen(*str);
|
|
||||||
for (size_t i = 0; i < length; i++) {
|
|
||||||
size_t j = length - i - 1;
|
|
||||||
if ((*str)[j] == '/') {
|
|
||||||
(*str)[j] = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Get Binary Directory (Remember To Free)
|
|
||||||
char *get_binary_directory() {
|
|
||||||
// Get Path To Current Executable
|
|
||||||
char *exe = realpath("/proc/self/exe", NULL);
|
|
||||||
ALLOC_CHECK(exe);
|
|
||||||
|
|
||||||
// Chop Off Last Component
|
|
||||||
chop_last_component(&exe);
|
|
||||||
|
|
||||||
// Return
|
|
||||||
return exe;
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void run_simple_command(const char *const command[], const char *error);
|
|
||||||
|
|
||||||
void chop_last_component(char **str);
|
|
||||||
char *get_binary_directory();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,47 +1,12 @@
|
||||||
project(libreborn)
|
project(libreborn)
|
||||||
|
|
||||||
# Config
|
add_library(reborn-util STATIC src/util/elf.c src/util/exec.c src/util/string.c src/util/util.c)
|
||||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/libreborn")
|
target_include_directories(reborn-util PUBLIC include)
|
||||||
configure_file(include/libreborn/config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/libreborn/config.h" ESCAPE_QUOTES @ONLY)
|
|
||||||
|
|
||||||
# Util
|
|
||||||
add_library(reborn-util SHARED src/util/exec.c src/util/string.c src/util/util.c src/util/log.c src/util/cp437.cpp)
|
|
||||||
target_include_directories(
|
|
||||||
reborn-util
|
|
||||||
PUBLIC
|
|
||||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
|
||||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
|
|
||||||
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/libreborn>"
|
|
||||||
)
|
|
||||||
target_link_libraries(reborn-util PRIVATE utf8cpp)
|
|
||||||
# Install
|
|
||||||
install(TARGETS reborn-util DESTINATION "${MCPI_LIB_DIR}")
|
|
||||||
# SDK
|
|
||||||
if(BUILD_ARM_COMPONENTS)
|
if(BUILD_ARM_COMPONENTS)
|
||||||
install(TARGETS reborn-util EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
add_library(reborn-patch SHARED src/patch/patch.c)
|
||||||
install(DIRECTORY "include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/libreborn")
|
target_link_libraries(reborn-patch dl reborn-util)
|
||||||
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/libreborn")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Patch
|
|
||||||
if(BUILD_ARM_COMPONENTS)
|
|
||||||
add_library(reborn-patch SHARED src/patch/patch.cpp src/patch/segments.cpp src/patch/code-block.cpp src/patch/instruction.cpp)
|
|
||||||
target_link_libraries(reborn-patch dl pthread reborn-util)
|
|
||||||
target_compile_definitions(reborn-patch PUBLIC -DREBORN_HAS_PATCH_CODE)
|
target_compile_definitions(reborn-patch PUBLIC -DREBORN_HAS_PATCH_CODE)
|
||||||
# Install
|
# Install
|
||||||
install(TARGETS reborn-patch DESTINATION "${MCPI_LIB_DIR}")
|
install(TARGETS reborn-patch DESTINATION "${MCPI_LIB_DIR}")
|
||||||
# SDK
|
|
||||||
install(TARGETS reborn-patch EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Fake LibPNG To Satisy Symbol Versioning Requirement
|
|
||||||
if(BUILD_ARM_COMPONENTS)
|
|
||||||
add_library(fake-libpng SHARED src/fake-libpng/empty.c)
|
|
||||||
set_target_properties(fake-libpng PROPERTIES
|
|
||||||
OUTPUT_NAME "png12"
|
|
||||||
SOVERSION 0
|
|
||||||
LINK_OPTIONS "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/fake-libpng/empty.vers"
|
|
||||||
)
|
|
||||||
# Install
|
|
||||||
install(TARGETS fake-libpng DESTINATION "${MCPI_LIB_DIR}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define GUI_TITLE "Minecraft: Pi Edition: Reborn"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue