Compare commits
17 Commits
4a69d38e35
...
00f8ed4752
Author | SHA1 | Date | |
---|---|---|---|
00f8ed4752 | |||
0fd8ba7de9 | |||
07baea7b5a | |||
8792e5749d | |||
53b2c20b8b | |||
244a69d1aa | |||
a1f777f632 | |||
5d8a1e4230 | |||
742ead51e1 | |||
c33a27b2ea | |||
c1377d4f2a | |||
e0ebc7fc32 | |||
0fcda17120 | |||
e9e9b90bdb | |||
0fd562af40 | |||
1eb06b6b60 | |||
c6983ac6c5 |
4
.gitignore
vendored
4
.gitignore
vendored
@ -4,3 +4,7 @@ debian/tmp
|
||||
build
|
||||
CMakeLists.txt.user
|
||||
*.autosave
|
||||
AppImageBuilder.yml
|
||||
appimage-builder-cache
|
||||
AppDir
|
||||
*.zsync
|
||||
|
8
.gitmodules
vendored
8
.gitmodules
vendored
@ -6,3 +6,11 @@
|
||||
path = dependencies/zlib/src
|
||||
url = https://github.com/madler/zlib.git
|
||||
shallow = true
|
||||
[submodule "dependencies/glfw/src"]
|
||||
path = dependencies/glfw/src
|
||||
url = https://github.com/glfw/glfw.git
|
||||
shallow = true
|
||||
[submodule "dependencies/zenity/src"]
|
||||
path = dependencies/zenity/src
|
||||
url = https://gitea.thebrokenrail.com/TheBrokenRail/zenity.git
|
||||
shallow = true
|
||||
|
@ -7,6 +7,7 @@ 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")
|
||||
@ -25,14 +26,6 @@ else()
|
||||
message(FATAL_ERROR "Invalid Mode")
|
||||
endif()
|
||||
|
||||
# Use Clang By Default
|
||||
if(NOT DEFINED CMAKE_C_COMPILER)
|
||||
set(CMAKE_C_COMPILER "clang")
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_CXX_COMPILER)
|
||||
set(CMAKE_CXX_COMPILER "clang++")
|
||||
endif()
|
||||
|
||||
# Utility Functions
|
||||
include(cmake/util.cmake)
|
||||
|
||||
@ -47,18 +40,13 @@ 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")
|
||||
set(MCPI_FALLBACK_LIB_DIR "${MCPI_INSTALL_DIR}/fallback-lib")
|
||||
|
||||
# Optimizations
|
||||
# Build Mode
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
endif()
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
add_compile_options(-O3)
|
||||
else()
|
||||
add_compile_options(-g)
|
||||
add_definitions(-DDEBUG)
|
||||
endif()
|
||||
|
||||
# Start Project
|
||||
project(minecraft-pi-reborn)
|
||||
@ -73,6 +61,13 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "" FORCE)
|
||||
endif()
|
||||
|
||||
# Optimizations
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
add_compile_options(-O3)
|
||||
else()
|
||||
add_compile_options(-g)
|
||||
endif()
|
||||
|
||||
# Use LLD When Using Clang
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
add_link_options("-fuse-ld=lld")
|
||||
@ -81,10 +76,11 @@ endif()
|
||||
# PIC
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
|
||||
|
||||
# Buld LibPNG + ZLib + Download Minecraft: Pi Edition
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
add_subdirectory(dependencies)
|
||||
endif()
|
||||
# Fast Math
|
||||
add_compile_options(-ffast-math)
|
||||
|
||||
# Buld Dependencies
|
||||
add_subdirectory(dependencies)
|
||||
|
||||
# Warnings
|
||||
add_compile_options(-Wall -Wextra -Werror -Wpointer-arith -Wshadow -Wnull-dereference)
|
||||
@ -93,9 +89,6 @@ add_definitions(-D_GNU_SOURCE)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
# Fast Math
|
||||
add_compile_options(-ffast-math)
|
||||
|
||||
# Specify Constants
|
||||
if(MCPI_SERVER_MODE)
|
||||
add_definitions(-DMCPI_SERVER_MODE)
|
||||
@ -103,6 +96,9 @@ endif()
|
||||
if(MCPI_HEADLESS_MODE)
|
||||
add_definitions(-DMCPI_HEADLESS_MODE)
|
||||
endif()
|
||||
if(MCPI_IS_APPIMAGE_BUILD)
|
||||
add_definitions(-DMCPI_IS_APPIMAGE_BUILD)
|
||||
endif()
|
||||
|
||||
# Version
|
||||
file(STRINGS VERSION VERSION)
|
||||
|
24
Dockerfile
24
Dockerfile
@ -1,21 +1,31 @@
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# Copy DEB
|
||||
ADD ./out/minecraft-pi-reborn-server_*_amd64.deb /root
|
||||
|
||||
# Install
|
||||
RUN \
|
||||
apt-get update && \
|
||||
apt-get install -y tini && \
|
||||
(dpkg -i /root/*.deb || :) && \
|
||||
apt-get install -y tini sed && \
|
||||
apt-get --fix-broken install -y && \
|
||||
rm -f /root/*.deb && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy AppImage
|
||||
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
|
||||
RUN mkdir /data
|
||||
WORKDIR /data
|
||||
|
||||
# Setup Entrypoint
|
||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||
CMD ["minecraft-pi-reborn-server"]
|
||||
CMD ["/app/squashfs-root/AppRun"]
|
||||
|
4
Jenkinsfile
vendored
4
Jenkinsfile
vendored
@ -4,7 +4,7 @@ pipeline {
|
||||
stage('Debian Bullseye') {
|
||||
agent {
|
||||
docker {
|
||||
image 'debian:bullseye'
|
||||
filename 'scripts/ci/Dockerfile'
|
||||
args '-v /var/run/docker.sock:/var/run/docker.sock'
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@ pipeline {
|
||||
}
|
||||
post {
|
||||
success {
|
||||
archiveArtifacts artifacts: 'out/*.deb', fingerprint: true
|
||||
archiveArtifacts artifacts: 'out/*.AppImage*', fingerprint: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,122 +1,11 @@
|
||||
# Sanity Check Return
|
||||
function(sanity_check_return ret)
|
||||
if(NOT ret EQUAL "0")
|
||||
message(FATAL_ERROR "Process Failed")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Get Host Architecture
|
||||
find_program(UNAME uname /bin /usr/bin /usr/local/bin REQUIRED)
|
||||
execute_process(
|
||||
COMMAND "${UNAME}" "-m"
|
||||
OUTPUT_VARIABLE HOST_ARCHITECTURE
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE ret
|
||||
)
|
||||
sanity_check_return("${ret}")
|
||||
|
||||
# Get Include Directories
|
||||
function(get_include_dirs target compiler result)
|
||||
# Get Tool Name
|
||||
set(tool "cc1")
|
||||
if(compiler MATCHES "^.*g\\+\\+$")
|
||||
set(tool "cc1plus")
|
||||
endif()
|
||||
|
||||
# Get Tool Path
|
||||
execute_process(
|
||||
COMMAND "${compiler}" "-print-prog-name=${tool}"
|
||||
ERROR_QUIET
|
||||
OUTPUT_VARIABLE tool
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE ret
|
||||
)
|
||||
sanity_check_return("${ret}")
|
||||
|
||||
# Run Tool To Get Include Path
|
||||
set(tool_output "")
|
||||
execute_process(
|
||||
COMMAND "${tool}" "-quiet" "-v" "-imultiarch" "${target}"
|
||||
OUTPUT_QUIET
|
||||
ERROR_VARIABLE tool_output
|
||||
ERROR_STRIP_TRAILING_WHITESPACE
|
||||
INPUT_FILE "/dev/null"
|
||||
RESULT_VARIABLE ret
|
||||
)
|
||||
sanity_check_return("${ret}")
|
||||
string(REPLACE "\n" ";" tool_output "${tool_output}")
|
||||
|
||||
# Loop
|
||||
set(parsing_include_section FALSE)
|
||||
foreach(line IN LISTS tool_output)
|
||||
# Check Include Section Status
|
||||
if(parsing_include_section)
|
||||
# Check If Include Section Is Over
|
||||
if(line MATCHES "^End of search list.$")
|
||||
# Starting Include Section
|
||||
set(parsing_include_section FALSE)
|
||||
break()
|
||||
else()
|
||||
# Parsing Include Section
|
||||
if(line MATCHES "^ .*$")
|
||||
# Strip Line
|
||||
string(STRIP "${line}" line)
|
||||
# Add To List
|
||||
list(APPEND "${result}" "${line}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
# Check If Include Section Is Starting
|
||||
if(line MATCHES "^#include <\\.\\.\\.> search starts here:$")
|
||||
# Starting Include Section
|
||||
set(parsing_include_section TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Return
|
||||
set("${result}" "${${result}}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Setup Include Directories
|
||||
function(setup_include_dirs compiler target result)
|
||||
# Get Full Compiler
|
||||
set(full_compiler "${target}-${compiler}")
|
||||
|
||||
# Get Include Directories
|
||||
set(include_dirs "")
|
||||
get_include_dirs("${target}" "${full_compiler}" include_dirs)
|
||||
|
||||
# Loop
|
||||
set(flags "")
|
||||
foreach(include_dir IN LISTS include_dirs)
|
||||
set(flags "${flags} -isystem ${include_dir}")
|
||||
endforeach()
|
||||
|
||||
# Return
|
||||
set("${result}" "${${result}} ${flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Setup Toolchain
|
||||
macro(setup_toolchain target)
|
||||
# Use ARM Cross-Compiler
|
||||
set(CMAKE_C_COMPILER "clang")
|
||||
set(CMAKE_C_COMPILER_TARGET "${target}")
|
||||
set(CMAKE_CXX_COMPILER "clang++")
|
||||
set(CMAKE_CXX_COMPILER_TARGET "${target}")
|
||||
set(CMAKE_C_COMPILER "${target}-gcc")
|
||||
set(CMAKE_CXX_COMPILER "${target}-g++")
|
||||
set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}")
|
||||
# Flags
|
||||
string(CONCAT NEW_FLAGS
|
||||
"-nostdinc "
|
||||
"-nostdinc++ "
|
||||
"-Wno-unused-command-line-argument"
|
||||
)
|
||||
set(CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS_INIT} ${NEW_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} ${NEW_FLAGS}")
|
||||
# Include Directories
|
||||
setup_include_dirs("gcc" "${target}" CMAKE_C_FLAGS_INIT)
|
||||
setup_include_dirs("g++" "${target}" CMAKE_CXX_FLAGS_INIT)
|
||||
# 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()
|
||||
|
7
debian/client-amd64
vendored
7
debian/client-amd64
vendored
@ -1,7 +0,0 @@
|
||||
Package: minecraft-pi-reborn-client
|
||||
Version: ${VERSION}
|
||||
Maintainer: TheBrokenRail <connor24nolan@live.com>
|
||||
Description: Fun with Blocks
|
||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||
Architecture: amd64
|
||||
Depends: libc6, libstdc++6, libc6-armhf-cross, libstdc++6-armhf-cross, zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3, libopenal1, qemu-user
|
7
debian/client-arm64
vendored
7
debian/client-arm64
vendored
@ -1,7 +0,0 @@
|
||||
Package: minecraft-pi-reborn-client
|
||||
Version: ${VERSION}
|
||||
Maintainer: TheBrokenRail <connor24nolan@live.com>
|
||||
Description: Fun with Blocks
|
||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||
Architecture: arm64
|
||||
Depends: libc6, libstdc++6, libc6:armhf, libstdc++6:armhf, zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3, libopenal1
|
7
debian/client-armhf
vendored
7
debian/client-armhf
vendored
@ -1,7 +0,0 @@
|
||||
Package: minecraft-pi-reborn-client
|
||||
Version: ${VERSION}
|
||||
Maintainer: TheBrokenRail <connor24nolan@live.com>
|
||||
Description: Fun with Blocks
|
||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||
Architecture: armhf
|
||||
Depends: libc6, libstdc++6, zenity, libgles1, libegl1, libglfw3 | libglfw3-wayland, libfreeimage3, libopenal1
|
7
debian/server-amd64
vendored
7
debian/server-amd64
vendored
@ -1,7 +0,0 @@
|
||||
Package: minecraft-pi-reborn-server
|
||||
Version: ${VERSION}
|
||||
Maintainer: TheBrokenRail <connor24nolan@live.com>
|
||||
Description: Fun with Blocks
|
||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||
Architecture: amd64
|
||||
Depends: libc6, libstdc++6, libc6-armhf-cross, libstdc++6-armhf-cross, qemu-user
|
7
debian/server-arm64
vendored
7
debian/server-arm64
vendored
@ -1,7 +0,0 @@
|
||||
Package: minecraft-pi-reborn-server
|
||||
Version: ${VERSION}
|
||||
Maintainer: TheBrokenRail <connor24nolan@live.com>
|
||||
Description: Fun with Blocks
|
||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||
Architecture: arm64
|
||||
Depends: libc6, libstdc++6, libc6:armhf, libstdc++6:armhf
|
7
debian/server-armhf
vendored
7
debian/server-armhf
vendored
@ -1,7 +0,0 @@
|
||||
Package: minecraft-pi-reborn-server
|
||||
Version: ${VERSION}
|
||||
Maintainer: TheBrokenRail <connor24nolan@live.com>
|
||||
Description: Fun with Blocks
|
||||
Homepage: https://www.minecraft.net/en-us/edition/pi
|
||||
Architecture: armhf
|
||||
Depends: libc6, libstdc++6
|
18
dependencies/CMakeLists.txt
vendored
18
dependencies/CMakeLists.txt
vendored
@ -1,10 +1,22 @@
|
||||
project(dependencies)
|
||||
|
||||
# ZLib
|
||||
add_subdirectory(zlib)
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
add_subdirectory(zlib)
|
||||
endif()
|
||||
# LibPNG
|
||||
add_subdirectory(libpng)
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
add_subdirectory(libpng)
|
||||
endif()
|
||||
# Minecraft: Pi Edition
|
||||
if(NOT MCPI_OPEN_SOURCE_ONLY)
|
||||
if(BUILD_ARM_COMPONENTS AND NOT MCPI_OPEN_SOURCE_ONLY)
|
||||
add_subdirectory(minecraft-pi)
|
||||
endif()
|
||||
# GLFW
|
||||
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
|
||||
add_subdirectory(glfw)
|
||||
endif()
|
||||
# Zenity (Minimal Build)
|
||||
if(BUILD_NATIVE_COMPONENTS AND NOT MCPI_HEADLESS_MODE)
|
||||
add_subdirectory(zenity)
|
||||
endif()
|
||||
|
22
dependencies/glfw/CMakeLists.txt
vendored
Normal file
22
dependencies/glfw/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
project(glfw)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w)
|
||||
|
||||
## GLFW
|
||||
|
||||
# Download
|
||||
set(BUILD_SHARED_LIBS FALSE)
|
||||
set(GLFW_BUILD_EXAMPLES FALSE)
|
||||
set(GLFW_BUILD_TESTS FALSE)
|
||||
set(GLFW_BUILD_DOCS FALSE)
|
||||
set(GLFW_INSTALL FALSE)
|
||||
set(GLFW_BUILD_WIN32 FALSE)
|
||||
set(GLFW_BUILD_COCOA FALSE)
|
||||
set(GLFW_BUILD_X11 TRUE)
|
||||
set(GLFW_BUILD_WAYLAND TRUE)
|
||||
set(GLFW_LIBRARY_TYPE "STATIC")
|
||||
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||
|
||||
# Ensure Build
|
||||
add_custom_target(glfw-build ALL DEPENDS glfw)
|
1
dependencies/glfw/src
vendored
Submodule
1
dependencies/glfw/src
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit adc202d2c3182ca6ad8344624941e56d8e0bc493
|
15
dependencies/zenity/CMakeLists.txt
vendored
Normal file
15
dependencies/zenity/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
project(zenity)
|
||||
|
||||
# Silence Warnings
|
||||
add_compile_options(-w)
|
||||
|
||||
## Zenity
|
||||
|
||||
# Download
|
||||
add_subdirectory(src EXCLUDE_FROM_ALL)
|
||||
|
||||
# Ensure Build
|
||||
add_custom_target(zenity-build ALL DEPENDS zenity)
|
||||
|
||||
# Install
|
||||
install(TARGETS zenity DESTINATION "${MCPI_BIN_DIR}")
|
1
dependencies/zenity/src
vendored
Submodule
1
dependencies/zenity/src
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 4663a8656d8c12be00286ee10aae2ff55ff589af
|
@ -1,23 +1,5 @@
|
||||
# Building
|
||||
|
||||
## Build Options
|
||||
* ``MCPI_BUILD_MODE``
|
||||
* ``arm``: Only Build ARM Components
|
||||
* ``native``: Only Build Native Components
|
||||
* ``both`` (Default): Build Both ARM And Native Components For ARM
|
||||
* ``MCPI_SERVER_MODE``
|
||||
* ``ON``: Enable Server Mode
|
||||
* ``OFF`` (Default): Disable Server Mode
|
||||
* ``MCPI_HEADLESS_MODE``
|
||||
* ``ON`` (Default In Server Mode): Enable Headless Mode
|
||||
* ``OFF`` (Default In Client Mode): Disable Headless Mode
|
||||
* ``MCPI_USE_MEDIA_LAYER_PROXY``
|
||||
* ``ON``: Enable The Media Layer Proxy
|
||||
* ``OFF`` (Default): Disable The Media Layer Proxy
|
||||
* ``MCPI_OPEN_SOURCE_ONLY``
|
||||
* ``ON``: Only Install Open-Source Code (Will Result In Broken Install)
|
||||
* ``OFF`` (Default): Install All Code
|
||||
|
||||
## Build Dependencies
|
||||
* Common
|
||||
* ARM Compiler
|
||||
@ -40,37 +22,13 @@
|
||||
* OpenAL
|
||||
* Zenity
|
||||
|
||||
## Two-Step Build
|
||||
Use this when the host architecture is not ARM.
|
||||
|
||||
## Instructions
|
||||
```sh
|
||||
# Create Build Directory
|
||||
mkdir build && cd build
|
||||
|
||||
# Build ARM Components
|
||||
mkdir arm && cd arm
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=../../cmake/armhf-toolchain.cmake -DMCPI_BUILD_MODE=arm ../..
|
||||
make -j$(nproc) && sudo make install
|
||||
cd ../
|
||||
|
||||
# Build Native Components
|
||||
mkdir native && cd native
|
||||
cmake -DMCPI_BUILD_MODE=native ../..
|
||||
make -j$(nproc) && sudo make install
|
||||
cd ../../
|
||||
./scripts/build.sh <client|server> <armhf|arm64|i686|amd64>
|
||||
```
|
||||
|
||||
This will most likely not compile by itself. You will want to enable either server mode or the Media Layer Proxy.
|
||||
|
||||
## One-Step Build
|
||||
Use this when the host architecture is ARM.
|
||||
|
||||
### Custom CMake Arguments
|
||||
```sh
|
||||
# Create Build Directory
|
||||
mkdir build && cd build
|
||||
|
||||
# Build
|
||||
cmake ..
|
||||
make -j$(nproc) && sudo make install
|
||||
cd ../
|
||||
./scripts/setup.sh <client|server> <armhf|arm64|i686|amd64> <Custom CMake Arguments>
|
||||
./scripts/build.sh <client|server> <armhf|arm64|i686|amd64>
|
||||
```
|
||||
|
@ -1,7 +1,19 @@
|
||||
# Changelog
|
||||
|
||||
**2.3.0**
|
||||
* Switch To AppImage For Packaging
|
||||
* Prevent OpenAL From Crashing When Out Of Memory
|
||||
* Vendor GLFW & Zenity
|
||||
* Seamless Wayland Support
|
||||
* Add ``MCPI_DEBUG`` Environmental Variable
|
||||
* Add ``Disable Hosting LAN Worlds`` Feature Flag (Disabled By Default)
|
||||
* Add ``Fix Furnace Not Checking Item Auxiliary`` Feature Flag (Enabled By Default)
|
||||
* Add ``Disable Raw Mouse Motion (Not Recommended)`` Feature Flag (Disabled By Default) For Broken X11 Setups
|
||||
* Improve Build System
|
||||
* Improve Documentation
|
||||
|
||||
**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"
|
||||
|
||||
**2.2.10**
|
||||
@ -12,8 +24,8 @@
|
||||
* Store Files In `/usr/lib`
|
||||
|
||||
**2.2.8**
|
||||
* Add "Hide Chat Messages" Optional Feature Flag
|
||||
* Add "Remove Creative Mode Restrictions" Optional Feature Flag
|
||||
* Add ``Hide Chat Messages`` Optional Feature Flag
|
||||
* Add ``Remove Creative Mode Restrictions`` Optional Feature Flag
|
||||
* Improve GLFW->SDL Mouse Motion Event Conversion
|
||||
* Performance Optimizations
|
||||
* Make Majority Of Server-Specific Logging Code Also Apply To The Client
|
||||
@ -51,7 +63,7 @@
|
||||
|
||||
**2.2.0**
|
||||
* Sound Support
|
||||
* Split Off "Allow Joining Survival Servers" From Game-Mode Mod
|
||||
* Split Off ``Allow Joining Survival Servers`` From Game-Mode Mod
|
||||
* Separate Headless Code From Server Code
|
||||
* Fix Bug Where ``RakNetInstance`` Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened
|
||||
* Clean-Up Code
|
||||
|
@ -1,16 +1,39 @@
|
||||
# Command Line Arguments
|
||||
# Command Line Usage
|
||||
|
||||
## ``--print-available-feature-flags`` (Client Mode Only)
|
||||
If you run MCPI-Reborn with ``--print-available-feature-flags``, it will print the available feature flags and then immediately exit. The feature flags are printed in the following format:
|
||||
## Command Line Arguments
|
||||
|
||||
### ``--print-available-feature-flags`` (Client Mode Only)
|
||||
If you run MCPI-Reborn with ``--print-available-feature-flags``, it will print the available feature flags and then immediately exit.
|
||||
|
||||
The feature flags are printed in the following format:
|
||||
```
|
||||
TRUE This Flag Is On By Default
|
||||
FALSE This Flag Is Off By Default
|
||||
```
|
||||
|
||||
## ``--only-generate`` (Server Mode Only)
|
||||
### ``--only-generate`` (Server Mode Only)
|
||||
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`` (Client Mode Only)
|
||||
### ``--benchmark`` (Client Mode Only)
|
||||
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.
|
||||
|
||||
## Environmental Variables
|
||||
|
||||
### ``MCPI_DEBUG``
|
||||
This enables debug logging if you set it to any non-zero-length value.
|
||||
|
||||
### Client Mode Only
|
||||
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``
|
||||
This corresponds to ``--print-available-feature-flags``. This is just a list of all enabled feature flags separated by ``|``.
|
||||
|
||||
For instance, the string ``Feature A|Feature B`` would enable both ``Feature A`` and ``Feature B`` and *disable every other available feature flag*.
|
||||
|
||||
### ``MCPI_RENDER_DISTANCE``
|
||||
This is the render distance. The possible values are: ``Far``, ``Normal``, ``Short``, and ``Tiny``.
|
||||
|
||||
### ``MCPI_USERNAME``
|
||||
This is the username.
|
||||
|
@ -1,10 +1,6 @@
|
||||
# Manual Installation
|
||||
[Download Packages Here](https://jenkins.thebrokenrail.com/job/minecraft-pi-reborn/job/master/lastSuccessfulBuild/artifact/out/)
|
||||
|
||||
## Supported Distributions
|
||||
* Ubuntu 20.04+
|
||||
* Debian Bullseye+
|
||||
|
||||
## Picking A Package
|
||||
|
||||
### Name Format
|
||||
|
BIN
images/start.png
BIN
images/start.png
Binary file not shown.
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@ -14,5 +14,12 @@ if(BUILD_NATIVE_COMPONENTS)
|
||||
install_symlink("../${MCPI_INSTALL_DIR}/launcher" "bin/${MCPI_VARIANT_NAME}")
|
||||
if(NOT MCPI_SERVER_MODE)
|
||||
install(DIRECTORY "client-data/" DESTINATION ".")
|
||||
else()
|
||||
set(ICON_PATH "share/icons/hicolor/scalable/apps")
|
||||
install(
|
||||
FILES "client-data/${ICON_PATH}/com.thebrokenrail.MCPIReborn.png"
|
||||
DESTINATION "${ICON_PATH}"
|
||||
RENAME "com.thebrokenrail.MCPIRebornServer.png"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -29,3 +29,6 @@ TRUE External Server Support
|
||||
TRUE Load Language Files
|
||||
TRUE Implement Sound Engine
|
||||
TRUE Close Current Screen On Death
|
||||
FALSE Disable Raw Mouse Motion (Not Recommended)
|
||||
TRUE Fix Furnace Not Checking Item Auxiliary
|
||||
FALSE Disable Hosting LAN Worlds
|
||||
|
@ -1,7 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Name=Minecraft: Pi Edition: Reborn
|
||||
Comment=Fun with Blocks
|
||||
Icon=minecraft-pi-reborn-client
|
||||
Icon=com.thebrokenrail.MCPIReborn
|
||||
StartupNotify=false
|
||||
StartupWMClass=Minecraft: Pi Edition: Reborn
|
||||
Exec=minecraft-pi-reborn-client
|
Before Width: | Height: | Size: 100 KiB After Width: | Height: | Size: 100 KiB |
@ -31,14 +31,16 @@ static void trim(char **value) {
|
||||
*value = &(*value)[1];
|
||||
}
|
||||
}
|
||||
static void set_and_print_env(const char *name, char *value) {
|
||||
void set_and_print_env(const char *name, char *value) {
|
||||
// Set Variable With No Trailing Colon
|
||||
trim(&value);
|
||||
static const char *unmodified_name_prefix = "MCPI_";
|
||||
if (strncmp(unmodified_name_prefix, name, strlen(unmodified_name_prefix)) != 0) {
|
||||
trim(&value);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Print New Value
|
||||
INFO("Set %s = %s", name, value);
|
||||
#endif
|
||||
DEBUG("Set %s = %s", name, value);
|
||||
|
||||
// Set The Value
|
||||
setenv(name, value, 1);
|
||||
}
|
||||
@ -134,71 +136,27 @@ static void load(char **ld_preload, char *folder) {
|
||||
}
|
||||
}
|
||||
|
||||
#define MCPI_NAME "minecraft-pi"
|
||||
#define MCPI_BINARY "minecraft-pi"
|
||||
#define QEMU_BINARY "qemu-arm"
|
||||
|
||||
// Bootstrap
|
||||
void bootstrap(int argc, char *argv[]) {
|
||||
INFO("%s", "Configuring Game...");
|
||||
// Pre-Bootstrap
|
||||
void pre_bootstrap() {
|
||||
// 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 LD_LIBRARY_PATH
|
||||
{
|
||||
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH");
|
||||
// Add Library Directory
|
||||
char *new_ld_path;
|
||||
safe_asprintf(&new_ld_path, "%s/lib", binary_directory);
|
||||
// Add Existing LD_LIBRARY_PATH
|
||||
{
|
||||
char *value = get_env_safe("LD_LIBRARY_PATH");
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&new_ld_path, ":%s", value);
|
||||
}
|
||||
}
|
||||
// Load ARM Libraries
|
||||
#ifdef __ARM_ARCH
|
||||
string_append(&new_ld_path, "%s", ":/usr/lib/arm-linux-gnueabihf:/usr/arm-linux-gnueabihf/lib");
|
||||
#endif
|
||||
// Add Full Library Search Path
|
||||
{
|
||||
char *value = get_full_library_search_path();
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&new_ld_path, ":%s", value);
|
||||
}
|
||||
free(value);
|
||||
}
|
||||
// Add Fallback Library Directory
|
||||
string_append(&new_ld_path, ":%s/fallback-lib", binary_directory);
|
||||
// Set And Free
|
||||
set_and_print_env("LD_LIBRARY_PATH", new_ld_path);
|
||||
free(new_ld_path);
|
||||
}
|
||||
|
||||
// Configure LD_PRELOAD
|
||||
{
|
||||
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_PRELOAD");
|
||||
char *new_ld_preload = NULL;
|
||||
safe_asprintf(&new_ld_preload, "%s", get_env_safe("LD_PRELOAD"));
|
||||
|
||||
// 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);
|
||||
|
||||
// Set LD_PRELOAD
|
||||
set_and_print_env("LD_PRELOAD", new_ld_preload);
|
||||
free(new_ld_preload);
|
||||
}
|
||||
|
||||
// Configure PATH
|
||||
{
|
||||
// Add Library Directory
|
||||
char *new_path;
|
||||
safe_asprintf(&new_path, "%s/lib", binary_directory);
|
||||
safe_asprintf(&new_path, "%s/bin", binary_directory);
|
||||
// Add Existing PATH
|
||||
{
|
||||
char *value = get_env_safe("PATH");
|
||||
@ -211,40 +169,181 @@ void bootstrap(int argc, char *argv[]) {
|
||||
free(new_path);
|
||||
}
|
||||
|
||||
// Start Game
|
||||
INFO("%s", "Starting Game...");
|
||||
// Free Binary Directory
|
||||
free(binary_directory);
|
||||
}
|
||||
|
||||
// Use Correct LibC
|
||||
#ifndef __ARM_ARCH
|
||||
setenv("QEMU_LD_PREFIX", "/usr/arm-linux-gnueabihf", 1);
|
||||
// Bootstrap
|
||||
void bootstrap(int argc, char *argv[]) {
|
||||
INFO("%s", "Configuring Game...");
|
||||
|
||||
// Get Binary Directory
|
||||
char *binary_directory = get_binary_directory();
|
||||
|
||||
// Handle AppImage
|
||||
char *usr_prefix = NULL;
|
||||
#ifdef MCPI_IS_APPIMAGE_BUILD
|
||||
usr_prefix = getenv("APPDIR");
|
||||
#endif
|
||||
if (usr_prefix == NULL) {
|
||||
usr_prefix = "";
|
||||
}
|
||||
|
||||
// Configure LD_LIBRARY_PATH
|
||||
{
|
||||
// Preserve
|
||||
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_LIBRARY_PATH");
|
||||
char *new_ld_path = NULL;
|
||||
|
||||
// Add Library Directory
|
||||
safe_asprintf(&new_ld_path, "%s/lib", binary_directory);
|
||||
|
||||
// Add MCPI_LD_LIBRARY_PATH
|
||||
{
|
||||
char *value = get_env_safe("MCPI_LD_LIBRARY_PATH");
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&new_ld_path, ":%s", value);
|
||||
}
|
||||
}
|
||||
|
||||
// Add LD_LIBRARY_PATH (ARM32 Only)
|
||||
#ifdef __arm__
|
||||
{
|
||||
char *value = get_env_safe("LD_LIBRARY_PATH");
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&new_ld_path, ":%s", value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create Full Path
|
||||
char *full_path = NULL;
|
||||
safe_asprintf(&full_path, "%s/" MCPI_NAME, 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 Full Library Search Path
|
||||
{
|
||||
char *value = get_full_library_search_path();
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&new_ld_path, ":%s", value);
|
||||
}
|
||||
free(value);
|
||||
}
|
||||
|
||||
// Add Fallback Library Directory
|
||||
string_append(&new_ld_path, ":%s/fallback-lib", binary_directory);
|
||||
|
||||
// Set And Free
|
||||
set_and_print_env("LD_LIBRARY_PATH", new_ld_path);
|
||||
free(new_ld_path);
|
||||
}
|
||||
|
||||
// Configure LD_PRELOAD
|
||||
{
|
||||
// Preserve
|
||||
PRESERVE_ENVIRONMENTAL_VARIABLE("LD_PRELOAD");
|
||||
char *new_ld_preload = NULL;
|
||||
|
||||
// Built-In Mods
|
||||
{
|
||||
// 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 MCPI_LD_PRELOAD
|
||||
{
|
||||
char *value = get_env_safe("MCPI_LD_PRELOAD");
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&new_ld_preload, ":%s", value);
|
||||
}
|
||||
}
|
||||
|
||||
// Add LD_PRELOAD (ARM32 Only)
|
||||
#ifdef __arm__
|
||||
{
|
||||
char *value = get_env_safe("MCPI_LD_PRELOAD");
|
||||
if (strlen(value) > 0) {
|
||||
string_append(&new_ld_preload, ":%s", value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set LD_PRELOAD
|
||||
set_and_print_env("LD_PRELOAD", new_ld_preload);
|
||||
free(new_ld_preload);
|
||||
}
|
||||
|
||||
// Resolve Binary Path & Set MCPI_DIRECTORY
|
||||
{
|
||||
// Resolve Full Binary Path
|
||||
char *full_path = NULL;
|
||||
safe_asprintf(&full_path, "%s/" MCPI_BINARY, binary_directory);
|
||||
char *resolved_path = realpath(full_path, NULL);
|
||||
ALLOC_CHECK(resolved_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);
|
||||
}
|
||||
|
||||
// Free Binary Directory
|
||||
free(binary_directory);
|
||||
|
||||
#ifdef __ARM_ARCH
|
||||
// Mark argc As Used
|
||||
(void) argc;
|
||||
// Run
|
||||
safe_execvpe(full_path, argv, environ);
|
||||
#else
|
||||
// Start Game
|
||||
INFO("%s", "Starting Game...");
|
||||
|
||||
// Arguments
|
||||
int argv_start = 2; // argv = &new_args[argv_start]
|
||||
char *new_args[argv_start /* 2 Potential Prefix Arguments (QEMU And Linker) */ + argc + 1 /* NULL-Terminator */]; //
|
||||
|
||||
// Copy Existing Arguments
|
||||
for (int i = 1; i < argc; i++) {
|
||||
new_args[i + argv_start] = argv[i];
|
||||
}
|
||||
// NULL-Terminator
|
||||
new_args[argv_start + argc] = NULL;
|
||||
|
||||
// Set Executable Argument
|
||||
new_args[argv_start] = getenv("MCPI_EXECUTABLE_PATH");
|
||||
|
||||
// Non-ARM32 Systems Need Manually Specified Linker
|
||||
#ifndef __arm__
|
||||
argv_start--;
|
||||
char *linker = NULL;
|
||||
safe_asprintf(&linker, "%s/usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3", usr_prefix);
|
||||
new_args[argv_start] = linker;
|
||||
|
||||
// Non-ARM Systems Need QEMU
|
||||
#ifndef __ARM_ARCH
|
||||
argv_start--;
|
||||
new_args[argv_start] = QEMU_BINARY;
|
||||
|
||||
// Prevent QEMU From Being Modded
|
||||
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_LIBRARY_PATH");
|
||||
PASS_ENVIRONMENTAL_VARIABLE_TO_QEMU("LD_PRELOAD");
|
||||
// Use QEMU
|
||||
#define EXE_INTERPRETER "qemu-arm"
|
||||
// Create Arguments List
|
||||
char *new_argv[argc + 2];
|
||||
for (int i = 1; i <= argc; i++) {
|
||||
new_argv[i + 1] = argv[i];
|
||||
}
|
||||
new_argv[0] = NULL; // Updated By safe_execvpe()
|
||||
new_argv[1] = full_path; // Path To MCPI
|
||||
// Run
|
||||
safe_execvpe(EXE_INTERPRETER, new_argv, environ);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Run
|
||||
char **new_argv = &new_args[argv_start];
|
||||
safe_execvpe(new_argv[0], new_argv, environ);
|
||||
}
|
||||
|
@ -4,6 +4,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void set_and_print_env(const char *name, char *value);
|
||||
|
||||
void pre_bootstrap();
|
||||
void bootstrap(int argc, char *argv[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -92,7 +92,7 @@ static void run_command_and_set_env(const char *env_name, char *command[]) {
|
||||
output[length - 1] = '\0';
|
||||
}
|
||||
// Set
|
||||
setenv(env_name, output, 1);
|
||||
set_and_print_env(env_name, output);
|
||||
}
|
||||
// Check Return Code
|
||||
if (return_code != 0) {
|
||||
@ -121,6 +121,9 @@ static void run_zenity_and_set_env(const char *env_name, std::vector<std::string
|
||||
|
||||
// Launch
|
||||
int main(int argc, char *argv[]) {
|
||||
// Pre-Bootstrap
|
||||
pre_bootstrap();
|
||||
|
||||
// Print Features
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--print-available-feature-flags") == 0) {
|
||||
|
@ -37,7 +37,10 @@ char *get_full_library_search_path() {
|
||||
output.pop_back();
|
||||
}
|
||||
// Close Process
|
||||
pclose(file);
|
||||
int ret = WEXITSTATUS(pclose(file));
|
||||
if (ret != 0) {
|
||||
ERR("ldconfig Failed: Exit Code: %i", ret);
|
||||
}
|
||||
// Return
|
||||
char *output_str = strdup(output.c_str());
|
||||
ALLOC_CHECK(output_str);
|
||||
|
@ -1,6 +1,17 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../bootstrap.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// Pre-Bootstrap
|
||||
pre_bootstrap();
|
||||
|
||||
// Set Home To Current Directory, So World Data Is Stored There
|
||||
char *launch_directory = getcwd(NULL, 0);
|
||||
set_and_print_env("HOME", launch_directory);
|
||||
free(launch_directory);
|
||||
|
||||
// Bootstrap
|
||||
bootstrap(argc, argv);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ add_library(reborn-headers INTERFACE)
|
||||
target_include_directories(reborn-headers INTERFACE include)
|
||||
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
add_library(reborn SHARED src/reborn.c)
|
||||
add_library(reborn SHARED src/patch.c)
|
||||
target_link_libraries(reborn dl reborn-headers)
|
||||
target_compile_definitions(reborn PUBLIC -DREBORN_HAS_COMPILED_CODE)
|
||||
# Install
|
||||
|
@ -13,7 +13,7 @@
|
||||
typedef void (*text_section_callback_t)(ElfW(Addr) section, ElfW(Word) size, void *data);
|
||||
static inline void iterate_text_sections(text_section_callback_t callback, void *data) {
|
||||
// Load Main Binary
|
||||
FILE *file_obj = fopen("/proc/self/exe", "rb");
|
||||
FILE *file_obj = fopen(getenv("MCPI_EXECUTABLE_PATH"), "rb");
|
||||
|
||||
// Verify Binary
|
||||
if (!file_obj) {
|
||||
|
@ -19,6 +19,18 @@ __attribute__((noreturn)) static inline void safe_execvpe(const char *pathname,
|
||||
ERR("%s", "Unknown execvpe() Error");
|
||||
}
|
||||
}
|
||||
|
||||
// Chop Off Last Component
|
||||
static inline 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)
|
||||
static inline char *get_binary_directory() {
|
||||
// Get Path To Current Executable
|
||||
@ -26,17 +38,12 @@ static inline char *get_binary_directory() {
|
||||
ALLOC_CHECK(exe);
|
||||
|
||||
// Chop Off Last Component
|
||||
int length = strlen(exe);
|
||||
for (int i = length - 1; i >= 0; i--) {
|
||||
if (exe[i] == '/') {
|
||||
exe[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
chop_last_component(&exe);
|
||||
|
||||
// Return
|
||||
return exe;
|
||||
}
|
||||
|
||||
// Safe execvpe() Relative To Binary
|
||||
__attribute__((noreturn)) static inline void safe_execvpe_relative_to_binary(const char *pathname, char *argv[], char *const envp[]) {
|
||||
// Get Binary Directory
|
||||
@ -49,3 +56,8 @@ __attribute__((noreturn)) static inline void safe_execvpe_relative_to_binary(con
|
||||
// Run
|
||||
safe_execvpe(full_path, argv, envp);
|
||||
}
|
||||
|
||||
// Get MCPI Directory
|
||||
static inline char *get_mcpi_directory() {
|
||||
return getenv("MCPI_DIRECTORY");
|
||||
}
|
||||
|
10
libreborn/include/libreborn/home.h
Normal file
10
libreborn/include/libreborn/home.h
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
// Minecraft Pi Game Data Root
|
||||
#ifndef MCPI_SERVER_MODE
|
||||
// Store Game Data In "~/.minecraft-pi" Instead Of "~/.minecraft" To Avoid Conflicts
|
||||
#define HOME_SUBDIRECTORY_FOR_GAME_DATA "/.minecraft-pi"
|
||||
#else
|
||||
// Store Game Data In $HOME Root (In Server Mode, $HOME Is Changed To The Launch Directory)
|
||||
#define HOME_SUBDIRECTORY_FOR_GAME_DATA ""
|
||||
#endif
|
@ -1,36 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
#include "exec.h"
|
||||
#include "elf.h"
|
||||
|
||||
#ifdef REBORN_HAS_COMPILED_CODE
|
||||
|
||||
// Patching Functions
|
||||
|
||||
void _overwrite_call(const char *file, int line, void *start, void *target);
|
||||
#define overwrite_call(start, target) _overwrite_call(__FILE__, __LINE__, start, target);
|
||||
|
||||
void _overwrite_calls(const char *file, int line, void *start, void *target);
|
||||
#define overwrite_calls(start, target) _overwrite_calls(__FILE__, __LINE__, start, target);
|
||||
|
||||
void _overwrite(const char *file, int line, void *start, void *target);
|
||||
#define overwrite(start, target) _overwrite(__FILE__, __LINE__, start, target);
|
||||
|
||||
void _patch(const char *file, int line, void *start, unsigned char patch[4]);
|
||||
#define patch(start, patch) _patch(__FILE__, __LINE__, start, patch);
|
||||
|
||||
void _patch_address(const char *file, int line, void *start, void *target);
|
||||
#define patch_address(start, target) _patch_address(__FILE__, __LINE__, start, target);
|
||||
|
||||
#endif // #ifdef __arm__
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include "home.h"
|
||||
#include "patch.h"
|
||||
|
@ -6,5 +6,6 @@
|
||||
// Logging
|
||||
#define INFO(format, ...) { fprintf(stderr, "[INFO]: " format "\n", __VA_ARGS__); }
|
||||
#define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", __VA_ARGS__); }
|
||||
#define DEBUG(format, ...) { const char *debug = getenv("MCPI_DEBUG"); if (debug != NULL && strlen(debug) > 0) { fprintf(stderr, "[DEBUG]: " format "\n", __VA_ARGS__); } }
|
||||
#define ERR(format, ...) { fprintf(stderr, "[ERR]: (%s:%i): " format "\n", __FILE__, __LINE__, __VA_ARGS__); exit(EXIT_FAILURE); }
|
||||
#define IMPOSSIBLE() ERR("%s", "This Should Never Be Called")
|
||||
|
30
libreborn/include/libreborn/patch.h
Normal file
30
libreborn/include/libreborn/patch.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Patching Functions
|
||||
|
||||
#ifdef REBORN_HAS_COMPILED_CODE
|
||||
|
||||
void _overwrite_call(const char *file, int line, void *start, void *target);
|
||||
#define overwrite_call(start, target) _overwrite_call(__FILE__, __LINE__, start, target);
|
||||
|
||||
void _overwrite_calls(const char *file, int line, void *start, void *target);
|
||||
#define overwrite_calls(start, target) _overwrite_calls(__FILE__, __LINE__, start, target);
|
||||
|
||||
void _overwrite(const char *file, int line, void *start, void *target);
|
||||
#define overwrite(start, target) _overwrite(__FILE__, __LINE__, start, target);
|
||||
|
||||
void _patch(const char *file, int line, void *start, unsigned char patch[4]);
|
||||
#define patch(start, patch) _patch(__FILE__, __LINE__, start, patch);
|
||||
|
||||
void _patch_address(const char *file, int line, void *start, void *target);
|
||||
#define patch_address(start, target) _patch_address(__FILE__, __LINE__, start, target);
|
||||
|
||||
#endif // #ifdef REBORN_HAS_COMPILED_CODE
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -79,9 +79,7 @@ static void update_code_block(void *target) {
|
||||
if (code_block == MAP_FAILED) {
|
||||
ERR("Unable To Allocate Code Block: %s", strerror(errno));
|
||||
}
|
||||
#ifdef DEBUG
|
||||
INFO("Code Block Allocated At: 0x%08x", (uint32_t) code_block);
|
||||
#endif
|
||||
DEBUG("Code Block Allocated At: 0x%08x", (uint32_t) code_block);
|
||||
}
|
||||
if (code_block_remaining < CODE_SIZE) {
|
||||
ERR("%s", "Maximum Amount Of overwrite_calls() Uses Reached");
|
||||
@ -138,11 +136,7 @@ void _overwrite(const char *file, int line, void *start, void *target) {
|
||||
}
|
||||
|
||||
// Print Patch Debug Data
|
||||
#ifdef DEBUG
|
||||
#define PATCH_PRINTF(file, line, start, str) if (file != NULL) fprintf(stderr, "[PATCH]: (%s:%i) Patching (0x%08x) - "str": 0x%02x 0x%02x 0x%02x 0x%02x\n", file, line, (uint32_t) start, data[0], data[1], data[2], data[3]);
|
||||
#else
|
||||
#define PATCH_PRINTF(file, line, start, str) { (void) file; (void) line; (void) start; (void) str; } // Mark As Used
|
||||
#endif
|
||||
#define PATCH_PRINTF(file, line, start, str) if (file != NULL) DEBUG("(%s:%i): Patching (0x%08x) - " str ": 0x%02x 0x%02x 0x%02x 0x%02x", file, line, (uint32_t) start, data[0], data[1], data[2], data[3]);
|
||||
|
||||
// Patch Instruction
|
||||
void _patch(const char *file, int line, void *start, unsigned char patch[4]) {
|
@ -22,8 +22,6 @@ if(TARGET media-layer-core)
|
||||
# Link
|
||||
target_link_libraries(media-layer-core media-layer-headers reborn-headers pthread dl)
|
||||
if(NOT MCPI_HEADLESS_MODE)
|
||||
# Find GLFW
|
||||
find_package(glfw3 3.3 REQUIRED)
|
||||
# Find FreeImage
|
||||
find_library(FREEIMAGE_LIBRARY NAMES freeimage libfreeimage.so.3 REQUIRED)
|
||||
# OpenAL
|
||||
|
@ -15,11 +15,12 @@ static std::vector<ALuint> &get_sources() {
|
||||
return sources;
|
||||
}
|
||||
|
||||
#define AL_ERROR_CHECK() \
|
||||
#define AL_ERROR_CHECK() AL_ERROR_CHECK_MANUAL(alGetError())
|
||||
#define AL_ERROR_CHECK_MANUAL(val) \
|
||||
{ \
|
||||
ALenum err = alGetError(); \
|
||||
if (err != AL_NO_ERROR) { \
|
||||
ERR("OpenAL Error: %s", alGetString(err)); \
|
||||
ALenum __err = val; \
|
||||
if (__err != AL_NO_ERROR) { \
|
||||
ERR("OpenAL Error: %s", alGetString(__err)); \
|
||||
} \
|
||||
}
|
||||
|
||||
@ -81,7 +82,15 @@ void media_audio_play(const char *source, const char *name, float x, float y, fl
|
||||
// Create Source
|
||||
ALuint al_source;
|
||||
alGenSources(1, &al_source);
|
||||
AL_ERROR_CHECK();
|
||||
// Special Out-Of-Memory Handling
|
||||
{
|
||||
ALenum err = alGetError();
|
||||
if (err == AL_OUT_OF_MEMORY) {
|
||||
return;
|
||||
} else {
|
||||
AL_ERROR_CHECK_MANUAL(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Set Properties
|
||||
alSourcef(al_source, AL_PITCH, pitch);
|
||||
|
@ -27,7 +27,7 @@ void media_set_interactable(int toggle) {
|
||||
// GLFW Code Not Needed In Headless Mode
|
||||
#ifndef MCPI_HEADLESS_MODE
|
||||
|
||||
static GLFWwindow *glfw_window;
|
||||
static GLFWwindow *glfw_window = NULL;
|
||||
|
||||
// Handle GLFW Error
|
||||
static void glfw_error(__attribute__((unused)) int error, const char *description) {
|
||||
@ -146,7 +146,7 @@ static SDLMod glfw_modifier_to_sdl_modifier(int mods) {
|
||||
}
|
||||
|
||||
// Pass Key Presses To SDL
|
||||
static void glfw_key(__attribute__((unused)) GLFWwindow *window, int key, int scancode, int action, __attribute__((unused)) int mods) {
|
||||
static void glfw_key(__attribute__((unused)) GLFWwindow *window, int key, int scancode, int action, int mods) {
|
||||
if (is_interactable) {
|
||||
SDL_Event event;
|
||||
int up = action == GLFW_RELEASE;
|
||||
@ -227,6 +227,20 @@ static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute_
|
||||
// Track Media Layer State
|
||||
static int is_running = 0;
|
||||
|
||||
// Track If Raw Mouse Motion Is Enabled
|
||||
static int raw_mouse_motion_enabled = 1;
|
||||
void media_set_raw_mouse_motion_enabled(int enabled) {
|
||||
raw_mouse_motion_enabled = enabled;
|
||||
#ifndef MCPI_HEADLESS_MODE
|
||||
if (is_running) {
|
||||
glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE);
|
||||
}
|
||||
#endif // #ifndef MCPI_HEADLESS_MODE
|
||||
if (!raw_mouse_motion_enabled) {
|
||||
WARN("%s", "Raw mouse motion has been DISABLED, this IS NOT recommended, and should only ever be used on systems that don't support or have broken raw mouse motion.");
|
||||
}
|
||||
}
|
||||
|
||||
// Disable V-Sync
|
||||
static int disable_vsync = 0;
|
||||
void media_disable_vsync() {
|
||||
@ -409,7 +423,7 @@ static void update_cursor() {
|
||||
glfwSetInputMode(glfw_window, GLFW_CURSOR, new_mode);
|
||||
|
||||
// Handle Cursor Lock/Unlock
|
||||
if ((new_mode == GLFW_CURSOR_DISABLED && old_mode != GLFW_CURSOR_DISABLED) || (new_mode != GLFW_CURSOR_DISABLED && old_mode == GLFW_CURSOR_DISABLED)) {
|
||||
if (raw_mouse_motion_enabled && ((new_mode == GLFW_CURSOR_DISABLED && old_mode != GLFW_CURSOR_DISABLED) || (new_mode != GLFW_CURSOR_DISABLED && old_mode == GLFW_CURSOR_DISABLED))) {
|
||||
// Use Raw Mouse Motion
|
||||
glfwSetInputMode(glfw_window, GLFW_RAW_MOUSE_MOTION, new_mode == GLFW_CURSOR_DISABLED ? GLFW_TRUE : GLFW_FALSE);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ void media_cleanup();
|
||||
void media_get_framebuffer_size(int *width, int *height);
|
||||
void media_set_interactable(int is_interactable);
|
||||
void media_disable_vsync();
|
||||
void media_set_raw_mouse_motion_enabled(int enabled);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ if(BUILD_NATIVE_COMPONENTS)
|
||||
target_link_libraries(media-layer-proxy-client media-layer-headers reborn-headers ${MEDIA_LAYER_PROXY_LIBS})
|
||||
target_compile_definitions(media-layer-proxy-client PRIVATE -DMEDIA_LAYER_PROXY_CLIENT)
|
||||
# Install
|
||||
install(TARGETS media-layer-proxy-client DESTINATION "${MCPI_LIB_DIR}")
|
||||
install(TARGETS media-layer-proxy-client DESTINATION "${MCPI_BIN_DIR}")
|
||||
endif()
|
||||
|
||||
if(BUILD_ARM_COMPONENTS)
|
||||
|
@ -32,6 +32,7 @@ static void sigusr1_handler(__attribute__((unused)) int sig) {
|
||||
void _check_proxy_state() {
|
||||
// Check Server State
|
||||
if (!parent_is_alive) {
|
||||
void_write_cache(); // Parent Is Dead, No Reason To Send A Dead Process Data
|
||||
PROXY_ERR("%s", "Server Terminated");
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,6 @@
|
||||
_check_proxy_state(); \
|
||||
if (!is_connection_open()) { \
|
||||
PROXY_ERR("%s", "Attempting To Access Closed Connection"); \
|
||||
} else { \
|
||||
_check_proxy_state(); \
|
||||
} \
|
||||
}
|
||||
void safe_read(void *buf, size_t len) {
|
||||
@ -63,27 +61,30 @@ void safe_write(void *buf, size_t len) {
|
||||
}
|
||||
// Flush Write Cache
|
||||
void flush_write_cache() {
|
||||
// Check Connection
|
||||
if (!is_connection_open()) {
|
||||
// Connection Closed
|
||||
return;
|
||||
}
|
||||
// Check Cache
|
||||
if (_write_cache == NULL || _write_cache_position < 1) {
|
||||
// Nothing To Write
|
||||
return;
|
||||
}
|
||||
// Write
|
||||
// Check Connection
|
||||
if (!is_connection_open()) {
|
||||
// Connection Closed
|
||||
return;
|
||||
}
|
||||
// Write & Reset
|
||||
size_t to_write = _write_cache_position;
|
||||
size_t old_write_cache_position = _write_cache_position;
|
||||
_write_cache_position = 0;
|
||||
while (to_write > 0) {
|
||||
CHECK_CONNECTION();
|
||||
ssize_t x = write(get_connection_write(), (void *) (((unsigned char *) _write_cache) + (_write_cache_position - to_write)), to_write);
|
||||
ssize_t x = write(get_connection_write(), (void *) (((unsigned char *) _write_cache) + (old_write_cache_position - to_write)), to_write);
|
||||
if (x == -1 && errno != EINTR) {
|
||||
PROXY_ERR("Failed Writing Data To Connection: %s", strerror(errno));
|
||||
}
|
||||
to_write -= x;
|
||||
}
|
||||
// Reset
|
||||
}
|
||||
void void_write_cache() {
|
||||
_write_cache_position = 0;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ extern "C" {
|
||||
__attribute__((visibility("internal"))) void safe_read(void *buf, size_t len);
|
||||
__attribute__((visibility("internal"))) void safe_write(void *buf, size_t len);
|
||||
__attribute__((visibility("internal"))) void flush_write_cache();
|
||||
__attribute__((visibility("internal"))) void void_write_cache();
|
||||
|
||||
// Read/Write 32-Bit Integers
|
||||
__attribute__((visibility("internal"))) uint32_t read_int();
|
||||
|
@ -336,3 +336,20 @@ CALL(63, media_disable_vsync, void, ()) {
|
||||
media_disable_vsync();
|
||||
#endif
|
||||
}
|
||||
|
||||
CALL(64, media_set_raw_mouse_motion_enabled, void, (int enabled)) {
|
||||
#if defined(MEDIA_LAYER_PROXY_SERVER)
|
||||
// Lock Proxy
|
||||
start_proxy_call();
|
||||
|
||||
// Arguments
|
||||
write_int(enabled);
|
||||
|
||||
// Release Proxy
|
||||
end_proxy_call();
|
||||
#else
|
||||
int enabled = read_int();
|
||||
// Run
|
||||
media_set_raw_mouse_motion_enabled(enabled);
|
||||
#endif
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ static void update_client_state(int is_alive, int status) {
|
||||
void _check_proxy_state() {
|
||||
// Check Client State
|
||||
if (!_client_is_alive) {
|
||||
void_write_cache(); // Child Is Dead, No Reason To Send A Dead Process Data
|
||||
if (WIFEXITED(_client_status)) {
|
||||
PROXY_ERR("Client Terminated: Exit Code: %i", WEXITSTATUS(_client_status));
|
||||
} else if (WIFSIGNALED(_client_status)) {
|
||||
|
@ -34,7 +34,7 @@ if(BUILD_ARM_COMPONENTS)
|
||||
|
||||
# MCPI Depends On GLESv2, But Uses GLESv1_CM
|
||||
install_symlink("libGLESv1_CM.so.1" "${MCPI_LIB_DIR}/libGLESv2.so")
|
||||
# Prevent MCPI From Linking To The Legacy GL Driver When Directly Linking To GL
|
||||
# Prevent MCPI From Linking To The Legacy GL Driver When Directly Linking To GL (RPI-Specific)
|
||||
if(NOT MCPI_HEADLESS_MODE AND NOT MCPI_USE_MEDIA_LAYER_PROXY)
|
||||
# Symlinks
|
||||
install_symlink("/usr/lib/arm-linux-gnueabihf/libEGL.so.1" "${MCPI_LIB_DIR}/libEGL.so")
|
||||
|
@ -29,7 +29,7 @@ static char *run_command(char *command, int *return_code) {
|
||||
}
|
||||
|
||||
// Return
|
||||
*return_code = pclose(out);
|
||||
*return_code = WEXITSTATUS(pclose(out));
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,10 @@ int feature_has(const char *name, int server_default) {
|
||||
tok = strtok(NULL, "|");
|
||||
}
|
||||
free(features);
|
||||
#ifdef DEBUG
|
||||
INFO("Feature: %s: %s", name, ret ? "Enabled" : "Disabled");
|
||||
#endif
|
||||
|
||||
// Log
|
||||
DEBUG("Feature: %s: %s", name, ret ? "Enabled" : "Disabled");
|
||||
|
||||
// Return
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,46 +1,17 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
|
||||
#include "home.h"
|
||||
#include "../init/init.h"
|
||||
|
||||
// Minecraft Pi User Data Root
|
||||
#ifndef MCPI_SERVER_MODE
|
||||
// Store Game Data In "~/.minecraft-pi" Instead Of "~/.minecraft" To Avoid Conflicts
|
||||
#define NEW_PATH "/.minecraft-pi"
|
||||
#else
|
||||
// Store Game Data In Launch Directory
|
||||
#define NEW_PATH ""
|
||||
|
||||
// Store Launch Directory
|
||||
__attribute__((constructor)) static char *get_launch_directory() {
|
||||
static char *launch_directory = NULL;
|
||||
if (launch_directory == NULL) {
|
||||
launch_directory = getcwd(NULL, 0);
|
||||
}
|
||||
return launch_directory;
|
||||
}
|
||||
__attribute__((destructor)) static void free_launch_directory() {
|
||||
free(get_launch_directory());
|
||||
}
|
||||
|
||||
// Pretend $HOME Is Launch Directory
|
||||
HOOK(getenv, char *, (const char *name)) {
|
||||
if (strcmp(name, "HOME") == 0) {
|
||||
return get_launch_directory();
|
||||
} else {
|
||||
ensure_getenv();
|
||||
return (*real_getenv)(name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get MCPI Home Directory
|
||||
char *home_get() {
|
||||
static char *dir = NULL;
|
||||
// Load
|
||||
if (dir == NULL) {
|
||||
safe_asprintf(&dir, "%s" NEW_PATH, getenv("HOME"));
|
||||
safe_asprintf(&dir, "%s" HOME_SUBDIRECTORY_FOR_GAME_DATA, getenv("HOME"));
|
||||
}
|
||||
// Return
|
||||
return dir;
|
||||
@ -53,12 +24,13 @@ __attribute__((destructor)) static void _free_home() {
|
||||
// Init
|
||||
void init_home() {
|
||||
// Store Data In ~/.minecraft-pi Instead Of ~/.minecraft
|
||||
patch_address((void *) default_path, (void *) NEW_PATH);
|
||||
patch_address((void *) default_path, (void *) HOME_SUBDIRECTORY_FOR_GAME_DATA);
|
||||
|
||||
// Change Directory To Binary Directory Manually
|
||||
unsigned char nop_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
|
||||
patch((void *) 0xe0ac, nop_patch);
|
||||
char *binary_directory = get_binary_directory();
|
||||
chdir(binary_directory);
|
||||
free(binary_directory);
|
||||
char *binary_directory = get_mcpi_directory();
|
||||
if (chdir(binary_directory) != 0) {
|
||||
ERR("Unable To Change Directory: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <libreborn/libreborn.h>
|
||||
#include <symbols/minecraft.h>
|
||||
#include <media-layer/core.h>
|
||||
|
||||
#include "../feature/feature.h"
|
||||
#include "../init/init.h"
|
||||
@ -46,4 +47,9 @@ void init_input() {
|
||||
|
||||
// Allow Attacking Mobs
|
||||
_init_attack();
|
||||
|
||||
// Disable Raw Mouse Motion
|
||||
if (feature_has("Disable Raw Mouse Motion (Not Recommended)", 9)) {
|
||||
media_set_raw_mouse_motion_enabled(0);
|
||||
}
|
||||
}
|
||||
|
@ -145,6 +145,40 @@ static void LocalPlayer_die_injection(unsigned char *entity, unsigned char *caus
|
||||
(*LocalPlayer_die)(entity, cause);
|
||||
}
|
||||
|
||||
// Fix Furnace Not Checking Item Auxiliary When Inserting New Item
|
||||
static int32_t FurnaceScreen_handleAddItem_injection(unsigned char *furnace_screen, int32_t slot, ItemInstance const *item) {
|
||||
// Get Existing Item
|
||||
unsigned char *tile_entity = *(unsigned char **) (furnace_screen + FurnaceScreen_tile_entity_property_offset);
|
||||
unsigned char *tile_entity_vtable = *(unsigned char **) tile_entity;
|
||||
FurnaceTileEntity_getItem_t FurnaceTileEntity_getItem = *(FurnaceTileEntity_getItem_t *) (tile_entity_vtable + FurnaceTileEntity_getItem_vtable_offset);
|
||||
ItemInstance *existing_item = (*FurnaceTileEntity_getItem)(tile_entity, slot);
|
||||
|
||||
// Check Item
|
||||
int valid;
|
||||
if (item->id == existing_item->id && item->auxiliary == existing_item->auxiliary) {
|
||||
// Item Matches, Is Valid
|
||||
valid = 1;
|
||||
} else {
|
||||
// Item Doesn't Match, Check If Existing Item Is Empty
|
||||
if ((existing_item->id | existing_item->count | existing_item->auxiliary) == 0) {
|
||||
// Existing Item Is Empty, Is Valid
|
||||
valid = 1;
|
||||
} else {
|
||||
// Existing Item Isn't Empty, Isn't Valid
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Call Original Method
|
||||
if (valid) {
|
||||
// Valid
|
||||
return (*FurnaceScreen_handleAddItem)(furnace_screen, slot, item);
|
||||
} else {
|
||||
// Invalid
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Init
|
||||
void init_misc() {
|
||||
// Remove Invalid Item Background (A Red Background That Appears For Items That Are Not Included In The gui_blocks Atlas)
|
||||
@ -177,6 +211,11 @@ void init_misc() {
|
||||
patch_address(LocalPlayer_die_vtable_addr, (void *) LocalPlayer_die_injection);
|
||||
}
|
||||
|
||||
// Fix Furnace Not Checking Item Auxiliary When Inserting New Item
|
||||
if (feature_has("Fix Furnace Not Checking Item Auxiliary", 0)) {
|
||||
overwrite_calls((void *) FurnaceScreen_handleAddItem, (void *) FurnaceScreen_handleAddItem_injection);
|
||||
}
|
||||
|
||||
// Init C++ And Logging
|
||||
_init_misc_cpp();
|
||||
_init_misc_logging();
|
||||
|
@ -46,6 +46,7 @@ static int peaceful_mode;
|
||||
static int anaglyph;
|
||||
static int smooth_lighting;
|
||||
static int render_distance;
|
||||
static int server_visible;
|
||||
// Configure Options
|
||||
static void Minecraft_init_injection(unsigned char *this) {
|
||||
// Call Original Method
|
||||
@ -64,6 +65,8 @@ static void Minecraft_init_injection(unsigned char *this) {
|
||||
*(options + Options_ambient_occlusion_property_offset) = smooth_lighting;
|
||||
// Render Distance
|
||||
*(int32_t *) (options + Options_render_distance_property_offset) = render_distance;
|
||||
// Server Visible
|
||||
*(options + Options_server_visible_property_offset) = server_visible;
|
||||
}
|
||||
|
||||
// Init
|
||||
@ -86,6 +89,8 @@ void init_options() {
|
||||
#else // #ifndef MCPI_SERVER_MODE
|
||||
render_distance = 3;
|
||||
#endif // #ifndef MCPI_SERVER_MODE
|
||||
// Server Visible
|
||||
server_visible = !feature_has("Disable Hosting LAN Worlds", 0);
|
||||
|
||||
// Set Options
|
||||
overwrite_calls((void *) Minecraft_init, (void *) Minecraft_init_injection);
|
||||
|
@ -10,10 +10,12 @@
|
||||
|
||||
#include "../home/home.h"
|
||||
|
||||
// Check If String Starts With Prefix
|
||||
static int starts_with(const char *s, const char *t) {
|
||||
return strncmp(s, t, strlen(t)) == 0;
|
||||
}
|
||||
|
||||
// Get Override Path For File (If It Exists)
|
||||
char *override_get_path(const char *filename) {
|
||||
// Get MCPI Home Path
|
||||
char *home_path = home_get();
|
||||
@ -23,9 +25,8 @@ char *override_get_path(const char *filename) {
|
||||
|
||||
// Get Data Path
|
||||
char *data = NULL;
|
||||
char *binary_directory = get_binary_directory();
|
||||
char *binary_directory = get_mcpi_directory();
|
||||
safe_asprintf(&data, "%s/data", binary_directory);
|
||||
free(binary_directory);
|
||||
int data_length = strlen(data);
|
||||
|
||||
// Get Full Path
|
||||
|
@ -23,15 +23,11 @@ std::string _sound_get_source_file() {
|
||||
// Resolve
|
||||
|
||||
// Get Binary Directory
|
||||
char *binary_directory = get_binary_directory();
|
||||
|
||||
char *binary_directory = get_mcpi_directory();
|
||||
// Get Full Path
|
||||
char *full_path = NULL;
|
||||
safe_asprintf(&full_path, "%s/" SOURCE_FILE_BASE, binary_directory);
|
||||
|
||||
// Free Binary Directory
|
||||
free(binary_directory);
|
||||
|
||||
// Handle Overrides
|
||||
char *overridden_full_path = override_get_path(full_path);
|
||||
if (overridden_full_path != NULL) {
|
||||
|
@ -1,14 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
# Clean Prefix
|
||||
rm -rf out
|
||||
|
||||
# Build
|
||||
./scripts/build.sh client amd64
|
||||
./scripts/build.sh server amd64
|
||||
./scripts/build.sh client arm64
|
||||
./scripts/build.sh server arm64
|
||||
./scripts/build.sh client armhf
|
||||
./scripts/build.sh server armhf
|
@ -2,48 +2,29 @@
|
||||
|
||||
set -e
|
||||
|
||||
# ARM Toolchain File
|
||||
ARM_TOOLCHAIN_FILE="$(pwd)/cmake/armhf-toolchain.cmake"
|
||||
|
||||
# Build
|
||||
build() {
|
||||
# Find Toolchain
|
||||
local toolchain_file="$(pwd)/cmake/$2-toolchain.cmake"
|
||||
if [ ! -f "${toolchain_file}" ]; then
|
||||
echo "Invalid Architecture: $2" > /dev/stderr
|
||||
exit 1
|
||||
# Use Build Dir
|
||||
if [ ! -d "build/${MODE}-${ARCH}" ]; then
|
||||
./scripts/setup.sh "${MODE}" "${ARCH}"
|
||||
fi
|
||||
|
||||
# Create Build Dir
|
||||
rm -rf "build/$1-$2"
|
||||
mkdir -p "build/$1-$2"
|
||||
cd "build/$1-$2"
|
||||
cd "build/${MODE}-${ARCH}"
|
||||
|
||||
# Create Prefix
|
||||
local prefix="$(cd ../../; pwd)/out/$1-$2"
|
||||
local prefix="$(cd ../../; pwd)/out/${MODE}-${ARCH}"
|
||||
rm -rf "${prefix}"
|
||||
mkdir -p "${prefix}"
|
||||
|
||||
# Prepare
|
||||
local extra_arg='-DMCPI_USE_MEDIA_LAYER_PROXY=ON'
|
||||
if [ "$1" = "server" ]; then
|
||||
extra_arg='-DMCPI_SERVER_MODE=ON'
|
||||
fi
|
||||
|
||||
# Build ARM Components
|
||||
mkdir arm
|
||||
cd arm
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE="${ARM_TOOLCHAIN_FILE}" -DMCPI_BUILD_MODE=arm "${extra_arg}" ../../..
|
||||
make -j$(nproc)
|
||||
make install DESTDIR="${prefix}"
|
||||
cmake --build .
|
||||
DESTDIR="${prefix}" cmake --install .
|
||||
cd ../
|
||||
|
||||
# Build Native Components
|
||||
mkdir native
|
||||
cd native
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE="${toolchain_file}" -DMCPI_BUILD_MODE=native "${extra_arg}" ../../..
|
||||
make -j$(nproc)
|
||||
make install DESTDIR="${prefix}"
|
||||
cmake --build .
|
||||
DESTDIR="${prefix}" cmake --install .
|
||||
cd ../
|
||||
|
||||
# Exit
|
||||
@ -52,40 +33,33 @@ build() {
|
||||
|
||||
# Build For ARM
|
||||
armhf_build() {
|
||||
# Create Build Dir
|
||||
rm -rf "build/$1-armhf"
|
||||
mkdir -p "build/$1-armhf"
|
||||
cd "build/$1-armhf"
|
||||
# Use Build Dir
|
||||
if [ ! -d "build/${MODE}-armhf" ]; then
|
||||
./scripts/setup.sh "${MODE}" armhf
|
||||
fi
|
||||
cd "build/${MODE}-armhf"
|
||||
|
||||
# Create Prefix
|
||||
local prefix="$(cd ../../; pwd)/out/$1-armhf"
|
||||
local prefix="$(cd ../../; pwd)/out/${MODE}-armhf"
|
||||
rm -rf "${prefix}"
|
||||
mkdir -p "${prefix}"
|
||||
|
||||
# Prepare
|
||||
local server_mode='OFF'
|
||||
if [ "$1" = "server" ]; then
|
||||
server_mode='ON'
|
||||
fi
|
||||
|
||||
# Build All Components
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE="${ARM_TOOLCHAIN_FILE}" -DMCPI_BUILD_MODE=both -DMCPI_SERVER_MODE="${server_mode}" ../..
|
||||
make -j$(nproc)
|
||||
make install DESTDIR="${prefix}"
|
||||
cmake --build .
|
||||
DESTDIR="${prefix}" cmake --install .
|
||||
|
||||
# Exit
|
||||
cd ../../
|
||||
}
|
||||
|
||||
# Verify Mode
|
||||
if [ "$1" != "client" ] && [ "$1" != "server" ]; then
|
||||
echo "Invalid Mode: $1" > /dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
# Variables
|
||||
MODE="$1"
|
||||
ARCH="$2"
|
||||
shift 2
|
||||
|
||||
# Build
|
||||
if [ "$2" = "armhf" ]; then
|
||||
armhf_build "$1"
|
||||
if [ "${ARCH}" = "armhf" ]; then
|
||||
armhf_build "${MODE}"
|
||||
else
|
||||
build "$1" "$2"
|
||||
build "${MODE}" "${ARCH}"
|
||||
fi
|
||||
|
12
scripts/ci/Dockerfile
Normal file
12
scripts/ci/Dockerfile
Normal file
@ -0,0 +1,12 @@
|
||||
FROM buildpack-deps:bullseye
|
||||
|
||||
# Setup
|
||||
ENV ARM_PACKAGES_SUPPORTED=1
|
||||
|
||||
# Install
|
||||
ADD ./scripts/install-dependencies.sh /
|
||||
RUN \
|
||||
apt-get update && \
|
||||
apt-get install --no-install-recommends -y sudo && \
|
||||
/install-dependencies.sh && \
|
||||
rm -rf /var/lib/apt/lists/*
|
@ -2,25 +2,10 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Install sudo
|
||||
apt-get update
|
||||
apt-get install -y sudo
|
||||
|
||||
# Prepare
|
||||
export ARM_PACKAGES_SUPPORTED=1
|
||||
|
||||
# Install Dependencies
|
||||
echo '==== Installing Dependencies ===='
|
||||
./scripts/install-dependencies.sh
|
||||
|
||||
# Build
|
||||
echo '==== Building ===='
|
||||
./scripts/build-all.sh
|
||||
# Build/Package
|
||||
echo '==== Building & Packaging ===='
|
||||
./scripts/package-all.sh
|
||||
|
||||
# Test
|
||||
echo '==== Testing ===='
|
||||
./scripts/test.sh
|
||||
|
||||
# Package
|
||||
echo '==== Packaging ===='
|
||||
./scripts/package.sh
|
||||
|
@ -2,5 +2,8 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Build Docker Image
|
||||
docker build -f scripts/ci/Dockerfile -t minecraft-pi-reborn-build .
|
||||
|
||||
# Run
|
||||
docker run --rm -v "$(pwd):/data" debian:bullseye sh -c "cd /data; ./scripts/ci/run.sh"
|
||||
docker run --rm -v "$(pwd):/data" -w '/data' -u '1000:1000' minecraft-pi-reborn-build ./scripts/ci/run.sh
|
||||
|
190
scripts/generate-appimage-builder-yaml.js
Executable file
190
scripts/generate-appimage-builder-yaml.js
Executable file
@ -0,0 +1,190 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Arguments
|
||||
if (process.argv.length < 4) {
|
||||
throw new Error('Invalid Arguments');
|
||||
}
|
||||
const mode = process.argv[2];
|
||||
const arch = process.argv[3];
|
||||
|
||||
// Data
|
||||
const id = `com.thebrokenrail.MCPIReborn${mode === 'server' ? 'Server' : ''}`;
|
||||
const name = `minecraft-pi-reborn-${mode}`;
|
||||
const updateURL = `https://jenkins.thebrokenrail.com/job/minecraft-pi-reborn/job/master/lastSuccessfulBuild/artifact/out/${name}-latest-${arch}.AppImage.zsync`;
|
||||
|
||||
// APT Data
|
||||
const apt_distribution = 'bullseye';
|
||||
const apt_key_url = 'https://ftp-master.debian.org/keys/archive-key-11.asc';
|
||||
|
||||
// Version
|
||||
const fs = require('fs');
|
||||
const version = fs.readFileSync('VERSION', 'utf8').trim();
|
||||
|
||||
// Packages/Dependencies
|
||||
const packages = [
|
||||
'libc6',
|
||||
'libc-bin',
|
||||
'libstdc++6'
|
||||
];
|
||||
if (mode === 'client') {
|
||||
// GLFW's Dependencies Aren't Included As They Should Be Provided By The Host System
|
||||
packages.push(
|
||||
'libgtk-3-0',
|
||||
'libglib2.0-0',
|
||||
'libgdk-pixbuf2.0-0',
|
||||
'shared-mime-info',
|
||||
'libfreeimage3',
|
||||
'libopenal1'
|
||||
);
|
||||
}
|
||||
if (arch !== 'armhf') {
|
||||
packages.push(
|
||||
'libc6-armhf-cross',
|
||||
'libstdc++6-armhf-cross'
|
||||
);
|
||||
if (arch !== 'arm64') {
|
||||
packages.push('qemu-user');
|
||||
}
|
||||
}
|
||||
|
||||
// Package Exclusions
|
||||
const packageExclusions = [
|
||||
// Exclude Unneeded Packages
|
||||
'humanity-icon-theme',
|
||||
'adwaita-icon-theme',
|
||||
'libxml2',
|
||||
'*systemd*',
|
||||
'dconf-service',
|
||||
'dconf-gsettings-backend',
|
||||
'libgnutls*',
|
||||
'librest-*',
|
||||
'libcups2',
|
||||
'libcolord2',
|
||||
'libmount1'
|
||||
];
|
||||
|
||||
// APT
|
||||
const apt = {
|
||||
arch: arch,
|
||||
sources: [
|
||||
{
|
||||
sourceline: `deb [arch=${arch}] http://deb.debian.org/debian/ ${apt_distribution} main`,
|
||||
key_url: apt_key_url
|
||||
},
|
||||
{
|
||||
sourceline: `deb [arch=${arch}] http://deb.debian.org/debian/ ${apt_distribution}-updates main`,
|
||||
key_url: apt_key_url
|
||||
}
|
||||
],
|
||||
include: packages,
|
||||
exclude: packageExclusions
|
||||
};
|
||||
|
||||
// Get Architecture Triplet
|
||||
const triplet = {
|
||||
'amd64': 'x86_64-linux-gnu',
|
||||
'i386': 'i386-linux-gnu',
|
||||
'arm64': 'aarch64-linux-gnu',
|
||||
'armhf': 'arm-linux-gnueabihf'
|
||||
}[arch];
|
||||
if (!triplet) {
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
// Files
|
||||
const files = {
|
||||
exclude: [
|
||||
// Exclude Unused Files
|
||||
`usr/lib/${triplet}/gconv`,
|
||||
'usr/share/man',
|
||||
'usr/share/doc/*/README.*',
|
||||
'usr/share/doc/*/changelog.*',
|
||||
'usr/share/doc/*/NEWS.*',
|
||||
'usr/share/doc/*/TODO.*',
|
||||
'usr/include',
|
||||
'usr/share/locale',
|
||||
'usr/share/help',
|
||||
'usr/bin/update-mime-database'
|
||||
]
|
||||
};
|
||||
|
||||
// Script After Bundling Dependencies
|
||||
const afterBundle = [
|
||||
// Remove Unused QEMU Binaries
|
||||
'find ./AppDir/usr/bin -maxdepth 1 -name \'qemu-*\' -a ! -name \'qemu-arm\' -delete'
|
||||
];
|
||||
|
||||
// Runtime
|
||||
const runtime = {
|
||||
env: mode === 'client' ? {
|
||||
// Make GTK Work (Zenity Uses GTK)
|
||||
GTK_EXE_PREFIX: '${APPDIR}/usr',
|
||||
GTK_PATH: `\${APPDIR}/usr/lib/${triplet}/gtk-3.0`,
|
||||
GTK_DATA_PREFIX: '${APPDIR}',
|
||||
GTK_THEME: 'Default',
|
||||
XDG_DATA_DIRS: '${APPDIR}/share:${APPDIR}/usr/share',
|
||||
APPDIR_LIBRARY_PATH: `\${APPDIR}/usr/lib/${triplet}:\${APPDIR}/usr/${triplet}/lib:\${APPDIR}/lib/${triplet}:\${APPDIR}/usr/lib:\${APPDIR}/usr/lib/${triplet}/gdk-pixbuf-2.0/2.10.0/loaders`
|
||||
} : undefined,
|
||||
preserve: arch !== 'armhf' ? [
|
||||
// On non-ARM32 systems, an ARM32 linker is embedded, this
|
||||
// prevents AppImage-Builder from modifying ARM32 binaries
|
||||
// to use a (usually non-existent) system linker.
|
||||
`usr/lib/${name}/minecraft-pi`,
|
||||
`usr/lib/${name}/**/*.so`,
|
||||
'usr/arm-linux-gnueabihf/lib'
|
||||
] : undefined
|
||||
};
|
||||
|
||||
// AppDir
|
||||
const appDir = {
|
||||
path: `./AppDir`,
|
||||
app_info: {
|
||||
id: id,
|
||||
name: `${name}`,
|
||||
icon: id,
|
||||
version: version,
|
||||
exec: `usr/bin/${name}`,
|
||||
exec_args: '$@'
|
||||
},
|
||||
apt: apt,
|
||||
files: files,
|
||||
after_bundle: afterBundle,
|
||||
runtime: runtime
|
||||
};
|
||||
|
||||
// Build Script
|
||||
const script = [
|
||||
`rm -rf ./build/${mode}-${arch}`,
|
||||
`./scripts/setup.sh ${mode} ${arch} -DMCPI_IS_APPIMAGE_BUILD=ON`,
|
||||
`rm -rf ./out/${mode}-${arch}`,
|
||||
`./scripts/build.sh ${mode} ${arch}`,
|
||||
'rm -rf ./AppDir',
|
||||
`cp -ar ./out/${mode}-${arch} ./AppDir`
|
||||
];
|
||||
|
||||
// AppImage
|
||||
const appImageArch = {
|
||||
'amd64': 'x86_64',
|
||||
'i386': 'i686',
|
||||
'arm64': 'aarch64',
|
||||
'armhf': 'armhf'
|
||||
}[arch];
|
||||
if (!appImageArch) {
|
||||
throw new Error();
|
||||
}
|
||||
const appImage = {
|
||||
arch: appImageArch,
|
||||
file_name: `./out/${name}-${version}-${arch}.AppImage`,
|
||||
'update-information': `zsync|${updateURL}`
|
||||
};
|
||||
|
||||
// Root
|
||||
const root = {
|
||||
version: 1,
|
||||
AppDir: appDir,
|
||||
script: script,
|
||||
AppImage: appImage
|
||||
};
|
||||
|
||||
// Write
|
||||
fs.writeFileSync(`AppImageBuilder.yml`, JSON.stringify(root, null, 4));
|
@ -18,32 +18,102 @@ fi
|
||||
sudo apt-get update
|
||||
sudo apt-get dist-upgrade -y
|
||||
|
||||
# Install
|
||||
sudo apt-get install --no-install-recommends -y \
|
||||
ca-certificates \
|
||||
lsb-release \
|
||||
dpkg-dev \
|
||||
# Install Everything In One Go
|
||||
PKG_QUEUE=''
|
||||
queue_pkg() {
|
||||
PKG_QUEUE="${PKG_QUEUE} $@"
|
||||
}
|
||||
|
||||
# Build Tools
|
||||
queue_pkg \
|
||||
git \
|
||||
clang \
|
||||
lld \
|
||||
cmake \
|
||||
make \
|
||||
libglfw3 libglfw3-dev \
|
||||
libfreeimage3 libfreeimage-dev \
|
||||
ninja-build \
|
||||
crossbuild-essential-armhf \
|
||||
gcc g++ \
|
||||
nodejs
|
||||
|
||||
# Dependencies
|
||||
queue_pkg \
|
||||
libfreeimage3 libfreeimage-dev \
|
||||
libopenal-dev \
|
||||
qemu-user
|
||||
|
||||
# Install ARM Dependencies
|
||||
# GLFW Dependencies
|
||||
queue_pkg \
|
||||
libwayland-dev \
|
||||
libxkbcommon-dev \
|
||||
wayland-protocols \
|
||||
libx11-dev \
|
||||
libxcursor-dev \
|
||||
libxi-dev \
|
||||
libxinerama-dev \
|
||||
libxrandr-dev \
|
||||
libxext-dev
|
||||
|
||||
# Zenity Dependencies
|
||||
queue_pkg \
|
||||
libgtk-3-dev \
|
||||
libglib2.0-dev
|
||||
|
||||
# ARM Packages
|
||||
if [ ! -z "${ARM_PACKAGES_SUPPORTED}" ]; then
|
||||
sudo apt-get install --no-install-recommends -y \
|
||||
libglfw3:armhf libglfw3-dev:armhf \
|
||||
libfreeimage3:armhf \
|
||||
libopenal-dev:armhf \
|
||||
libglfw3:arm64 libglfw3-dev:arm64 \
|
||||
libfreeimage3:arm64 \
|
||||
libopenal-dev:arm64 \
|
||||
# Build Tools
|
||||
queue_pkg \
|
||||
crossbuild-essential-arm64
|
||||
|
||||
# Dependencies
|
||||
queue_pkg \
|
||||
libfreeimage3:armhf libfreeimage3:arm64 \
|
||||
libopenal-dev:armhf libopenal-dev:arm64
|
||||
|
||||
# GLFW Dependencies
|
||||
queue_pkg \
|
||||
libwayland-dev:armhf libwayland-dev:arm64 \
|
||||
libxkbcommon-dev:armhf libxkbcommon-dev:arm64 \
|
||||
libx11-dev:armhf libx11-dev:arm64 \
|
||||
libxcursor-dev:armhf libxcursor-dev:arm64 \
|
||||
libxi-dev:armhf libxi-dev:arm64 \
|
||||
libxinerama-dev:armhf libxinerama-dev:arm64 \
|
||||
libxrandr-dev:armhf libxrandr-dev:arm64 \
|
||||
libxext-dev:armhf libxext-dev:arm64
|
||||
|
||||
# Zenity Dependencies
|
||||
queue_pkg \
|
||||
libgtk-3-dev:armhf libgtk-3-dev:arm64 \
|
||||
libglib2.0-dev:armhf libglib2.0-dev:arm64
|
||||
fi
|
||||
|
||||
# Install appimagetool & appimage-builder Dependencies
|
||||
queue_pkg \
|
||||
python3-pip \
|
||||
python3-setuptools \
|
||||
patchelf \
|
||||
desktop-file-utils \
|
||||
libgdk-pixbuf2.0-dev \
|
||||
fakeroot \
|
||||
strace \
|
||||
fuse \
|
||||
gtk-update-icon-cache \
|
||||
shared-mime-info \
|
||||
sed
|
||||
|
||||
# Install Queue
|
||||
sudo apt-get install --no-install-recommends -y ${PKG_QUEUE}
|
||||
|
||||
# Download appimagetool
|
||||
sudo mkdir -p /opt
|
||||
sudo wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O /opt/appimagetool
|
||||
sudo chmod +x /opt/appimagetool
|
||||
# Workaround AppImage Issues With Docker
|
||||
cd /opt
|
||||
sudo sed -i '0,/AI\x02/{s|AI\x02|\x00\x00\x00|}' ./appimagetool
|
||||
sudo rm -rf /opt/squashfs-root /opt/appimagetool.AppDir
|
||||
sudo ./appimagetool --appimage-extract
|
||||
sudo rm -f ./appimagetool
|
||||
sudo mv /opt/squashfs-root /opt/appimagetool.AppDir
|
||||
sudo rm -f /usr/local/bin/appimagetool
|
||||
sudo ln -s /opt/appimagetool.AppDir/AppRun /usr/local/bin/appimagetool
|
||||
|
||||
# Install appimage-builder
|
||||
sudo pip3 install 'git+https://github.com/TheBrokenRail/appimage-builder.git@combined'
|
||||
|
14
scripts/package-all.sh
Executable file
14
scripts/package-all.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
# Clean Prefix
|
||||
rm -rf out
|
||||
|
||||
# Build
|
||||
./scripts/package.sh client amd64
|
||||
./scripts/package.sh server amd64
|
||||
./scripts/package.sh client arm64
|
||||
./scripts/package.sh server arm64
|
||||
./scripts/package.sh client armhf
|
||||
./scripts/package.sh server armhf
|
@ -2,36 +2,11 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Prepare
|
||||
VERSION="$(cat VERSION)"
|
||||
# Generate
|
||||
./scripts/generate-appimage-builder-yaml.js "$1" "$2"
|
||||
|
||||
# Common
|
||||
package() {
|
||||
local dir="out/$1"
|
||||
|
||||
# Create DEBIAN Dir
|
||||
rm -rf "${dir}/DEBIAN"
|
||||
mkdir -p "${dir}/DEBIAN"
|
||||
cp "debian/$1" "${dir}/DEBIAN/control"
|
||||
|
||||
# Format DEBIAN/control
|
||||
sed -i "s/\${VERSION}/${VERSION}/g" "${dir}/DEBIAN/control"
|
||||
|
||||
# Fix Permissions On Jenkins
|
||||
chmod -R g-s "${dir}"
|
||||
|
||||
# Package
|
||||
dpkg-deb --root-owner-group --build "${dir}" out
|
||||
}
|
||||
# Build/Package
|
||||
appimage-builder --recipe AppImageBuilder.yml
|
||||
|
||||
# Find And Package
|
||||
for dir in out/*; do
|
||||
# Check If Directory Exists
|
||||
if [ -d "${dir}" ]; then
|
||||
# Check If Debian Package Exists
|
||||
pkg="$(basename ${dir})"
|
||||
if [ -f "debian/${pkg}" ]; then
|
||||
package "${pkg}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
# Move ZSync
|
||||
mv "./minecraft-pi-reborn-$1-$(cat VERSION)-$2.AppImage.zsync" "./out/minecraft-pi-reborn-$1-latest-$2.AppImage.zsync"
|
||||
|
80
scripts/setup.sh
Executable file
80
scripts/setup.sh
Executable file
@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
# ARM Toolchain File
|
||||
ARM_TOOLCHAIN_FILE="$(pwd)/cmake/armhf-toolchain.cmake"
|
||||
|
||||
# Setup
|
||||
setup() {
|
||||
# Find Toolchain
|
||||
local toolchain_file="$(pwd)/cmake/${ARCH}-toolchain.cmake"
|
||||
if [ ! -f "${toolchain_file}" ]; then
|
||||
echo "Invalid Architecture: ${ARCH}" > /dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create Build Dir
|
||||
rm -rf "build/${MODE}-${ARCH}"
|
||||
mkdir -p "build/${MODE}-${ARCH}"
|
||||
cd "build/${MODE}-${ARCH}"
|
||||
|
||||
# Prepare
|
||||
local extra_arg='-DMCPI_USE_MEDIA_LAYER_PROXY=ON'
|
||||
if [ "${MODE}" = "server" ]; then
|
||||
extra_arg='-DMCPI_SERVER_MODE=ON'
|
||||
fi
|
||||
|
||||
# Build ARM Components
|
||||
mkdir arm
|
||||
cd arm
|
||||
cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE="${ARM_TOOLCHAIN_FILE}" -DMCPI_BUILD_MODE=arm "${extra_arg}" "$@" ../../..
|
||||
cd ../
|
||||
|
||||
# Build Native Components
|
||||
mkdir native
|
||||
cd native
|
||||
cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE="${toolchain_file}" -DMCPI_BUILD_MODE=native "${extra_arg}" "$@" ../../..
|
||||
cd ../
|
||||
|
||||
# Exit
|
||||
cd ../../
|
||||
}
|
||||
|
||||
# Setup For ARM
|
||||
armhf_setup() {
|
||||
# Create Build Dir
|
||||
rm -rf "build/${MODE}-armhf"
|
||||
mkdir -p "build/${MODE}-armhf"
|
||||
cd "build/${MODE}-armhf"
|
||||
|
||||
# Prepare
|
||||
local server_mode='OFF'
|
||||
if [ "${MODE}" = "server" ]; then
|
||||
server_mode='ON'
|
||||
fi
|
||||
|
||||
# Build All Components
|
||||
cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE="${ARM_TOOLCHAIN_FILE}" -DMCPI_BUILD_MODE=both -DMCPI_SERVER_MODE="${server_mode}" "$@" ../..
|
||||
|
||||
# Exit
|
||||
cd ../../
|
||||
}
|
||||
|
||||
# Variables
|
||||
MODE="$1"
|
||||
ARCH="$2"
|
||||
shift 2
|
||||
|
||||
# Verify Mode
|
||||
if [ "${MODE}" != "client" ] && [ "${MODE}" != "server" ]; then
|
||||
echo "Invalid Mode: ${MODE}" > /dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Setup
|
||||
if [ "${ARCH}" = "armhf" ]; then
|
||||
armhf_setup "$@"
|
||||
else
|
||||
setup "$@"
|
||||
fi
|
@ -2,6 +2,10 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Build Test
|
||||
./scripts/setup.sh server "$(dpkg-architecture -qDEB_BUILD_ARCH)"
|
||||
./scripts/build.sh server "$(dpkg-architecture -qDEB_BUILD_ARCH)"
|
||||
|
||||
# Add minecraft-pi-reborn-server To PATH
|
||||
export PATH="$(pwd)/out/server-$(dpkg-architecture -qDEB_BUILD_ARCH)/usr/bin:${PATH}"
|
||||
|
||||
|
@ -63,7 +63,7 @@ struct AABB {
|
||||
};
|
||||
|
||||
struct LevelSettings {
|
||||
unsigned long seed;
|
||||
int32_t seed;
|
||||
int32_t game_type;
|
||||
};
|
||||
|
||||
@ -243,6 +243,7 @@ static uint32_t Options_third_person_property_offset = 0xed; // unsigned char /
|
||||
static uint32_t Options_render_distance_property_offset = 0x10; // int32_t
|
||||
static uint32_t Options_sound_property_offset = 0x4; // int32_t
|
||||
static uint32_t Options_debug_property_offset = 0xee; // unsigned char / bool
|
||||
static uint32_t Options_server_visible_property_offset = 0x104; // unsigned char / bool
|
||||
|
||||
// MouseBuildInput
|
||||
|
||||
@ -401,6 +402,18 @@ static ProgressScreen_t ProgressScreen = (ProgressScreen_t) 0x37044;
|
||||
|
||||
static void *OptionsScreen_handleBackEvent_vtable_addr = (void *) 0x10499c;
|
||||
|
||||
// FurnaceScreen
|
||||
|
||||
typedef int32_t (*FurnaceScreen_handleAddItem_t)(unsigned char *furnace_screen, int32_t slot, ItemInstance const *item);
|
||||
static FurnaceScreen_handleAddItem_t FurnaceScreen_handleAddItem = (FurnaceScreen_handleAddItem_t) 0x327a0;
|
||||
|
||||
static uint32_t FurnaceScreen_tile_entity_property_offset = 0x1d0; // FurnaceTileEntity *
|
||||
|
||||
// FurnaceTileEntity
|
||||
|
||||
typedef ItemInstance *(*FurnaceTileEntity_getItem_t)(unsigned char *furnace_tile_entity, int32_t slot);
|
||||
static uint32_t FurnaceTileEntity_getItem_vtable_offset = 0x2c;
|
||||
|
||||
// Screen
|
||||
|
||||
typedef void (*Screen_updateEvents_t)(unsigned char *screen);
|
||||
@ -637,7 +650,7 @@ static AppPlatform_readAssetFile_t AppPlatform_readAssetFile = (AppPlatform_read
|
||||
|
||||
// Minecraft
|
||||
|
||||
typedef void (*Minecraft_selectLevel_t)(unsigned char *minecraft, std::string const& level_dir, std::string const& level_name, LevelSettings const& vsettings);
|
||||
typedef void (*Minecraft_selectLevel_t)(unsigned char *minecraft, std::string const& level_dir, std::string const& level_name, LevelSettings const& settings);
|
||||
static Minecraft_selectLevel_t Minecraft_selectLevel = (Minecraft_selectLevel_t) 0x16f38;
|
||||
|
||||
// ExternalFileLevelStorageSource
|
||||
|
Loading…
Reference in New Issue
Block a user