diff --git a/.gitignore b/.gitignore index 95c2f476..58bbd335 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -/out -/debian/tmp -/.vscode -/build -/CMakeLists.txt.user +out +debian/tmp +.vscode +build +CMakeLists.txt.user *.autosave diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..82965c68 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,8 @@ +[submodule "dependencies/libpng/src"] + path = dependencies/libpng/src + url = https://github.com/glennrp/libpng.git + shallow = true +[submodule "dependencies/zlib/src"] + path = dependencies/zlib/src + url = https://github.com/madler/zlib.git + shallow = true diff --git a/CMakeLists.txt b/CMakeLists.txt index ef87af9d..10923182 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ endif() # Setup ARM Cross Compilation if(USE_ARM32_TOOLCHAIN) - include(cmake/arm-toolchain.cmake) + include(cmake/armhf-toolchain.cmake) endif() # Utility Functions @@ -72,6 +72,14 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "/" CACHE PATH "" FORCE) endif() +# Use LLD When Using Clang +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + add_link_options("-fuse-ld=lld") +endif() + +# PIC +set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) + # Buld LibPNG + ZLib + Download Minecraft: Pi Edition if(BUILD_ARM_COMPONENTS) add_subdirectory(dependencies) @@ -84,11 +92,6 @@ add_definitions(-D_GNU_SOURCE) set(CMAKE_C_STANDARD 99) set(CMAKE_CXX_STANDARD 11) -# Use LLD When Using Clang -if(CMAKE_C_COMPILER_ID STREQUAL "Clang") - add_link_options("-fuse-ld=lld") -endif() - # Specify Constants if(MCPI_SERVER_MODE) add_definitions(-DMCPI_SERVER_MODE) diff --git a/VERSION b/VERSION index 530cdd91..5bc1cc43 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.4 +2.2.7 diff --git a/cmake/amd64-toolchain.cmake b/cmake/amd64-toolchain.cmake new file mode 100644 index 00000000..145f4911 --- /dev/null +++ b/cmake/amd64-toolchain.cmake @@ -0,0 +1,7 @@ +# Compile For x86_64 +include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake") +# Use x86_64 Cross-Compiler +setup_toolchain("x86_64-linux-gnu") +# Details +set(CMAKE_SYSTEM_NAME "Linux") +set(CMAKE_SYSTEM_PROCESSOR "x86_64") diff --git a/cmake/arm-toolchain.cmake b/cmake/arm-toolchain.cmake deleted file mode 100644 index 9ffecead..00000000 --- a/cmake/arm-toolchain.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# Compile For ARM -if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64_be" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "armv8b" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "armv8l") - # Force 32-Bit Compile - add_compile_options("-m32") -elseif(NOT CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm") - # Use ARM Cross-Compiler - include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake") - setup_toolchain("arm-linux-gnueabihf") -endif() -set(CMAKE_SYSTEM_NAME "Linux") -set(CMAKE_SYSTEM_PROCESSOR "arm") diff --git a/cmake/arm64-toolchain.cmake b/cmake/arm64-toolchain.cmake index 45cee3cd..9671e40a 100644 --- a/cmake/arm64-toolchain.cmake +++ b/cmake/arm64-toolchain.cmake @@ -1,8 +1,7 @@ # Compile For ARM64 -if(NOT (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64_be" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "armv8b" OR CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "armv8l")) - # Use ARM64 Cross-Compiler - include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake") - setup_toolchain("aarch64-linux-gnu") -endif() +include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake") +# Use ARM64 Cross-Compiler +setup_toolchain("aarch64-linux-gnu") +# Details set(CMAKE_SYSTEM_NAME "Linux") set(CMAKE_SYSTEM_PROCESSOR "aarch64") diff --git a/cmake/armhf-toolchain.cmake b/cmake/armhf-toolchain.cmake new file mode 100644 index 00000000..efcd9ddf --- /dev/null +++ b/cmake/armhf-toolchain.cmake @@ -0,0 +1,7 @@ +# Compile For ARM +include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake") +# Use ARM Cross-Compiler +setup_toolchain("arm-linux-gnueabihf") +# Details +set(CMAKE_SYSTEM_NAME "Linux") +set(CMAKE_SYSTEM_PROCESSOR "arm") diff --git a/cmake/base-toolchain.cmake b/cmake/base-toolchain.cmake index b5c8347e..08a50724 100644 --- a/cmake/base-toolchain.cmake +++ b/cmake/base-toolchain.cmake @@ -1,16 +1,102 @@ -# Pick GCC Version -macro(pick_gcc_version gcc_root gcc_version) - file(GLOB children RELATIVE "${gcc_root}" "${gcc_root}/*") - set("${gcc_version}" "") - foreach(child IN LISTS children) - if(IS_DIRECTORY "${gcc_root}/${child}" AND ("${${gcc_version}}" STREQUAL "" OR "${child}" GREATER_EQUAL "${${gcc_version}}")) - set("${gcc_version}" "${child}") +# 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() - if("${${gcc_version}}" STREQUAL "") - message(FATAL_ERROR "Unable To Pick GCC Version") - endif() -endmacro() + + # 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) @@ -20,20 +106,17 @@ macro(setup_toolchain target) set(CMAKE_CXX_COMPILER "clang++") set(CMAKE_CXX_COMPILER_TARGET "${target}") set(CMAKE_FIND_ROOT_PATH "/usr/${target}" "/usr/lib/${target}") - # Include Directories - pick_gcc_version("/usr/lib/gcc-cross/${target}" GCC_VERSION) + # Flags string(CONCAT NEW_FLAGS - "-nostdinc -nostdinc++ -Wno-unused-command-line-argument " - "-isystem /usr/${target}/include/c++/${GCC_VERSION} " - "-isystem /usr/${target}/include/c++/${GCC_VERSION}/${target} " - "-isystem /usr/${target}/include/c++/${GCC_VERSION}/backward " - "-isystem /usr/lib/gcc-cross/${target}/${GCC_VERSION}/include " - "-isystem /usr/lib/gcc-cross/${target}/${GCC_VERSION}/include-fixed " - "-isystem /usr/${target}/include " - "-isystem /usr/include" + "-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) endmacro() diff --git a/cmake/i686-toolchain.cmake b/cmake/i686-toolchain.cmake new file mode 100644 index 00000000..a8f0f945 --- /dev/null +++ b/cmake/i686-toolchain.cmake @@ -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") diff --git a/cmake/x86_64-toolchain.cmake b/cmake/x86_64-toolchain.cmake deleted file mode 100644 index 3ec02864..00000000 --- a/cmake/x86_64-toolchain.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# Compile For x86_64 -if(NOT CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64") - # Use x86_64 Cross-Compiler - include("${CMAKE_CURRENT_LIST_DIR}/base-toolchain.cmake") - setup_toolchain("x86_64-linux-gnu") -endif() -set(CMAKE_SYSTEM_NAME "Linux") -set(CMAKE_SYSTEM_PROCESSOR "x86_64") diff --git a/debian/client-x86_64 b/debian/client-amd64 similarity index 100% rename from debian/client-x86_64 rename to debian/client-amd64 diff --git a/debian/client-arm b/debian/client-armhf similarity index 100% rename from debian/client-arm rename to debian/client-armhf diff --git a/debian/server-x86_64 b/debian/server-amd64 similarity index 100% rename from debian/server-x86_64 rename to debian/server-amd64 diff --git a/debian/server-arm b/debian/server-armhf similarity index 100% rename from debian/server-arm rename to debian/server-armhf diff --git a/dependencies/libpng/CMakeLists.txt b/dependencies/libpng/CMakeLists.txt index b6560a0d..478460ed 100644 --- a/dependencies/libpng/CMakeLists.txt +++ b/dependencies/libpng/CMakeLists.txt @@ -1,28 +1,20 @@ project(libpng) -include(FetchContent) - # Silence Warnings add_compile_options(-w) ## LibPNG # Download -set(SKIP_INSTALL_ALL TRUE) # Skip Default LibPNG Installation -FetchContent_Declare( - libpng - GIT_REPOSITORY "https://github.com/glennrp/libpng.git" - GIT_TAG "v1.2.59" -) -FetchContent_Populate(libpng) -set(ZLIB_LIBRARY zlib) -set(ZLIB_INCLUDE_DIR "${zlib_SOURCE_DIR}" "${zlib_BINARY_DIR}") +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("${libpng_SOURCE_DIR}" "${libpng_BINARY_DIR}") +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 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}") - diff --git a/dependencies/libpng/src b/dependencies/libpng/src new file mode 160000 index 00000000..5bb5bf34 --- /dev/null +++ b/dependencies/libpng/src @@ -0,0 +1 @@ +Subproject commit 5bb5bf345aef1e62adcfe30791f4364730a2aede diff --git a/dependencies/minecraft-pi/CMakeLists.txt b/dependencies/minecraft-pi/CMakeLists.txt index 9deea304..647410df 100644 --- a/dependencies/minecraft-pi/CMakeLists.txt +++ b/dependencies/minecraft-pi/CMakeLists.txt @@ -13,4 +13,3 @@ FetchContent_Populate(minecraft-pi) # Install install(DIRECTORY "${minecraft-pi_SOURCE_DIR}/" DESTINATION "${MCPI_INSTALL_DIR}" USE_SOURCE_PERMISSIONS) - diff --git a/dependencies/zlib/CMakeLists.txt b/dependencies/zlib/CMakeLists.txt index 04cfd399..591ed9ab 100644 --- a/dependencies/zlib/CMakeLists.txt +++ b/dependencies/zlib/CMakeLists.txt @@ -1,23 +1,12 @@ project(zlib) -include(FetchContent) - # Silence Warnings add_compile_options(-w) ## zlib # Download -set(SKIP_INSTALL_ALL TRUE) # Skip Default ZLib Installation -FetchContent_Declare( - zlib - GIT_REPOSITORY "https://github.com/madler/zlib.git" - GIT_TAG "v1.2.11" -) -FetchContent_Populate(zlib) -include_directories("${zlib_SOURCE_DIR}" "${zlib_BINARY_DIR}") # Fix ZLib Build -add_subdirectory("${zlib_SOURCE_DIR}" "${zlib_BINARY_DIR}") - -# Install -install(TARGETS zlib DESTINATION "${MCPI_LIB_DIR}") +add_subdirectory(src EXCLUDE_FROM_ALL) +# Ensure Build +add_custom_target(zlib-build ALL DEPENDS zlibstatic) diff --git a/dependencies/zlib/src b/dependencies/zlib/src new file mode 160000 index 00000000..cacf7f1d --- /dev/null +++ b/dependencies/zlib/src @@ -0,0 +1 @@ +Subproject commit cacf7f1d4e3d44d871b605da3b647f07d718623f diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 86bafaee..f43fb192 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +**2.2.7** +* Fix Crash When OpenAL Is Unavailable +* Fix Command Input In Server + +**2.2.5** +* Fix Bug In Texture Scaling Code + +**2.2.5** +* Scale Animated Textures +* Add More Blocks To Expanded Creative Inventory +* Reduce Unnecessary Logging +* Log IPs In Server Mode + **2.2.4** * Instead Of Crashing, Disable Polling Block Hits In Survival Mode Using The API @@ -11,7 +24,7 @@ * Make Missing Sound Event Cause Warning Rather Than Crash **2.2.1** -* Prevent `random.burp` Sound From Crashing Game +* Prevent ``random.burp`` Sound From Crashing Game * Always Cleanup Media Layer, Even On Crash * Resolve All Sounds On Startup @@ -19,7 +32,7 @@ * Sound Support * Split Off "Allow Joining Survival Servers" From Game-Mode Mod * Separate Headless Code From Server Code -* Fix Bug Where `RakNetInstance` Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened +* Fix Bug Where ``RakNetInstance`` Starts Pinging Potential Servers Before The "Join Game" Screen Is Opened * Clean-Up Code * Remove Support For Debian Buster @@ -36,7 +49,7 @@ * Print Error Message If RakNet Fails To Start **2.1.4** -* Fix RakNet::RakString Security Bug +* Fix ``RakNet::RakString`` Security Bug **2.1.3** * Workaround Broken Library Search Path On Some ARM 32-Bit Systems @@ -74,7 +87,7 @@ * Optimize Media Layer Proxy **2.0.3** -* Make "kill" Admin Command Print Death Message +* Make ``kill`` Admin Command Print Death Message **2.0.2** * Fix Mouse Cursor Bugs diff --git a/images/start.png b/images/start.png index c56ab704..72011713 100644 Binary files a/images/start.png and b/images/start.png differ diff --git a/media-layer/core/src/audio/api.cpp b/media-layer/core/src/audio/api.cpp index 1aceb04a..44fe4fdf 100644 --- a/media-layer/core/src/audio/api.cpp +++ b/media-layer/core/src/audio/api.cpp @@ -25,90 +25,96 @@ static std::vector &get_sources() { // Update Listener void media_audio_update(float volume, float x, float y, float z, float yaw) { - // Update Listener Volume - alListenerf(AL_GAIN, volume); - AL_ERROR_CHECK(); + // Check + if (_media_audio_is_loaded()) { + // Update Listener Volume + alListenerf(AL_GAIN, volume); + AL_ERROR_CHECK(); - // Update Listener Position - alListener3f(AL_POSITION, x, y, z); - AL_ERROR_CHECK(); + // Update Listener Position + alListener3f(AL_POSITION, x, y, z); + AL_ERROR_CHECK(); - // Update Listener Orientation - float radian_yaw = yaw * (M_PI / 180); - ALfloat orientation[] = {-sinf(radian_yaw), 0.0f, cosf(radian_yaw), 0.0f, 1.0f, 0.0f}; - alListenerfv(AL_ORIENTATION, orientation); - AL_ERROR_CHECK(); + // Update Listener Orientation + float radian_yaw = yaw * (M_PI / 180); + ALfloat orientation[] = {-sinf(radian_yaw), 0.0f, cosf(radian_yaw), 0.0f, 1.0f, 0.0f}; + alListenerfv(AL_ORIENTATION, orientation); + AL_ERROR_CHECK(); - // Clear Finished Sources - std::vector::iterator it = get_sources().begin(); - while (it != get_sources().end()) { - ALuint source = *it; - bool remove = false; - // Check - if (source && alIsSource(source)) { - // Is Valid Source - ALint source_state; - alGetSourcei(source, AL_SOURCE_STATE, &source_state); - AL_ERROR_CHECK(); - if (source_state != AL_PLAYING) { - // Finished Playing - remove = true; - alDeleteSources(1, &source); + // Clear Finished Sources + std::vector::iterator it = get_sources().begin(); + while (it != get_sources().end()) { + ALuint source = *it; + bool remove = false; + // Check + if (source && alIsSource(source)) { + // Is Valid Source + ALint source_state; + alGetSourcei(source, AL_SOURCE_STATE, &source_state); AL_ERROR_CHECK(); + if (source_state != AL_PLAYING) { + // Finished Playing + remove = true; + alDeleteSources(1, &source); + AL_ERROR_CHECK(); + } + } else { + // Not A Source + remove = true; + } + // Remove If Needed + if (remove) { + it = get_sources().erase(it); + } else { + ++it; } - } else { - // Not A Source - remove = true; - } - // Remove If Needed - if (remove) { - it = get_sources().erase(it); - } else { - ++it; } } } void media_audio_play(const char *source, const char *name, float x, float y, float z, float pitch, float volume, int is_ui) { - // Load Sound - ALuint buffer = _media_audio_get_buffer(source, name); - if (volume > 0.0f && buffer) { - // Create Source - ALuint al_source; - alGenSources(1, &al_source); - AL_ERROR_CHECK(); + // Check + if (_media_audio_is_loaded()) { + // Load Sound + ALuint buffer = _media_audio_get_buffer(source, name); + if (volume > 0.0f && buffer) { + // Create Source + ALuint al_source; + alGenSources(1, &al_source); + AL_ERROR_CHECK(); - // Set Properties - alSourcef(al_source, AL_PITCH, pitch); - AL_ERROR_CHECK(); - alSourcef(al_source, AL_GAIN, volume); - AL_ERROR_CHECK(); - alSource3f(al_source, AL_POSITION, x, y, z); - AL_ERROR_CHECK(); - alSource3f(al_source, AL_VELOCITY, 0, 0, 0); - AL_ERROR_CHECK(); - alSourcei(al_source, AL_LOOPING, AL_FALSE); - AL_ERROR_CHECK(); - alSourcei(al_source, AL_SOURCE_RELATIVE, is_ui ? AL_TRUE : AL_FALSE); - AL_ERROR_CHECK(); + // Set Properties + alSourcef(al_source, AL_PITCH, pitch); + AL_ERROR_CHECK(); + alSourcef(al_source, AL_GAIN, volume); + AL_ERROR_CHECK(); + alSource3f(al_source, AL_POSITION, x, y, z); + AL_ERROR_CHECK(); + alSource3f(al_source, AL_VELOCITY, 0, 0, 0); + AL_ERROR_CHECK(); + alSourcei(al_source, AL_LOOPING, AL_FALSE); + AL_ERROR_CHECK(); + alSourcei(al_source, AL_SOURCE_RELATIVE, is_ui ? AL_TRUE : AL_FALSE); + AL_ERROR_CHECK(); - // Set Attenuation - alSourcei(al_source, AL_DISTANCE_MODEL, AL_LINEAR_DISTANCE); - AL_ERROR_CHECK(); - alSourcef(al_source, AL_MAX_DISTANCE, 16.0f); - AL_ERROR_CHECK(); - alSourcef(al_source, AL_ROLLOFF_FACTOR, 1.0f); - AL_ERROR_CHECK(); - alSourcef(al_source, AL_REFERENCE_DISTANCE, 0.0f); - AL_ERROR_CHECK(); + // Set Attenuation + alSourcei(al_source, AL_DISTANCE_MODEL, AL_LINEAR_DISTANCE); + AL_ERROR_CHECK(); + alSourcef(al_source, AL_MAX_DISTANCE, 16.0f); + AL_ERROR_CHECK(); + alSourcef(al_source, AL_ROLLOFF_FACTOR, 1.0f); + AL_ERROR_CHECK(); + alSourcef(al_source, AL_REFERENCE_DISTANCE, 0.0f); + AL_ERROR_CHECK(); - // Set Buffer - alSourcei(al_source, AL_BUFFER, buffer); - AL_ERROR_CHECK(); + // Set Buffer + alSourcei(al_source, AL_BUFFER, buffer); + AL_ERROR_CHECK(); - // Play - alSourcePlay(al_source); - AL_ERROR_CHECK(); - get_sources().push_back(al_source); + // Play + alSourcePlay(al_source); + AL_ERROR_CHECK(); + get_sources().push_back(al_source); + } } } diff --git a/media-layer/core/src/media.c b/media-layer/core/src/media.c index d2143784..d09fa32b 100644 --- a/media-layer/core/src/media.c +++ b/media-layer/core/src/media.c @@ -76,6 +76,10 @@ static SDLKey glfw_key_to_sdl_key(int key) { return SDLK_7; case GLFW_KEY_8: return SDLK_8; + case GLFW_KEY_9: + return SDLK_9; + case GLFW_KEY_0: + return SDLK_0; // UI Control case GLFW_KEY_ESCAPE: return SDLK_ESCAPE; diff --git a/media-layer/include/GLES/gl.h b/media-layer/include/GLES/gl.h index ba1d9fde..935917b2 100644 --- a/media-layer/include/GLES/gl.h +++ b/media-layer/include/GLES/gl.h @@ -7,6 +7,7 @@ extern "C" { #define GL_FALSE 0 #define GL_FOG_COLOR 0xb66 #define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_TEXTURE_BINDING_2D 0x8069 #define GL_UNSIGNED_BYTE 0x1401 #define GL_RGB 0x1907 #define GL_RGBA 0x1908 diff --git a/media-layer/include/SDL/SDL_events.h b/media-layer/include/SDL/SDL_events.h index 758de852..23946068 100644 --- a/media-layer/include/SDL/SDL_events.h +++ b/media-layer/include/SDL/SDL_events.h @@ -114,8 +114,8 @@ typedef struct SDL_JoyButtonEvent { typedef struct SDL_ResizeEvent { uint8_t type; - int w; - int h; + int32_t w; + int32_t h; } SDL_ResizeEvent; typedef struct SDL_ExposeEvent { @@ -128,14 +128,14 @@ typedef struct SDL_QuitEvent { typedef struct SDL_UserEvent { uint8_t type; - int code; - void *data1; - void *data2; + int32_t code; + uint32_t data1; + uint32_t data2; } SDL_UserEvent; typedef struct SDL_SysWMEvent { uint8_t type; - void *msg; + uint32_t msg; } SDL_SysWMEvent; typedef union SDL_Event { diff --git a/media-layer/proxy/src/GLESv1_CM.c b/media-layer/proxy/src/GLESv1_CM.c index 2eb0c6ca..8d7d0956 100644 --- a/media-layer/proxy/src/GLESv1_CM.c +++ b/media-layer/proxy/src/GLESv1_CM.c @@ -1099,6 +1099,7 @@ CALL(58, glIsEnabled, GLboolean, (GLenum cap)) { static int get_glGetIntegerv_params_size(GLenum pname) { switch (pname) { + case GL_TEXTURE_BINDING_2D: case GL_UNPACK_ALIGNMENT: { return 1; } diff --git a/media-layer/proxy/src/media-layer-core.c b/media-layer/proxy/src/media-layer-core.c index 850466d2..a7fffae0 100644 --- a/media-layer/proxy/src/media-layer-core.c +++ b/media-layer/proxy/src/media-layer-core.c @@ -9,116 +9,6 @@ #include "common/common.h" -// Read/Write SDL Events -static void write_SDL_Event(SDL_Event event) { - // Write EVent Type - write_int(event.type); - // Write Event Details - switch (event.type) { - // Focus Event - case SDL_ACTIVEEVENT: { - write_int(event.active.gain); - write_int(event.active.state); - break; - } - // Key Press Events - case SDL_KEYDOWN: - case SDL_KEYUP: { - write_int(event.key.state); - write_int(event.key.keysym.scancode); - write_int(event.key.keysym.sym); - write_int(event.key.keysym.mod); - write_int(event.key.keysym.unicode); - break; - } - // Mouse Motion Event - case SDL_MOUSEMOTION: { - write_int(event.motion.state); - write_int(event.motion.x); - write_int(event.motion.y); - write_int(event.motion.xrel); - write_int(event.motion.yrel); - break; - } - // Mouse Press Events - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: { - write_int(event.button.button); - write_int(event.button.state); - write_int(event.button.x); - write_int(event.button.y); - break; - } - // User-Specified Event (Repurposed As Unicode Character Event) - case SDL_USEREVENT: { - write_int(event.user.code); - break; - } - } -} -static SDL_Event read_SDL_Event() { - // Create Event - SDL_Event event; - event.type = read_int(); - // Read Event Details - switch (event.type) { - // Focus Event - case SDL_ACTIVEEVENT: { - event.active.gain = read_int(); - event.active.state = read_int(); - break; - } - // Key Press Events - case SDL_KEYDOWN: - case SDL_KEYUP: { - event.key.state = read_int(); - event.key.keysym.scancode = read_int(); - event.key.keysym.sym = read_int(); - event.key.keysym.mod = read_int(); - event.key.keysym.unicode = read_int(); - break; - } - // Mouse Motion Event - case SDL_MOUSEMOTION: { - event.motion.state = read_int(); - event.motion.x = read_int(); - event.motion.y = read_int(); - event.motion.xrel = read_int(); - event.motion.yrel = read_int(); - break; - } - // Mouse Press Events - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: { - event.button.button = read_int(); - event.button.state = read_int(); - event.button.x = read_int(); - event.button.y = read_int(); - break; - } - // Quit Event - case SDL_QUIT: { - break; - } - // User-Specified Event (Repurposed As Unicode Character Event) - case SDL_USEREVENT: { - event.user.code = read_int(); - break; - } - // Unsupported Event - default: { - INFO("Unsupported SDL Event: %u", event.type); - } - } - // Return -#pragma GCC diagnostic push -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -#endif - return event; -#pragma GCC diagnostic pop -} - // SDL Functions CALL(0, SDL_Init, int, (uint32_t flags)) { @@ -156,7 +46,7 @@ CALL(1, SDL_PollEvent, int, (SDL_Event *event)) { // Get Return Value int32_t ret = (int32_t) read_int(); if (ret) { - *event = read_SDL_Event(); + safe_read((void *) event, sizeof (SDL_Event)); } // Release Proxy @@ -171,7 +61,7 @@ CALL(1, SDL_PollEvent, int, (SDL_Event *event)) { // Return Values write_int(ret); if (ret) { - write_SDL_Event(event); + safe_write((void *) &event, sizeof (SDL_Event)); } #endif } @@ -182,7 +72,7 @@ CALL(2, SDL_PushEvent, int, (SDL_Event *event)) { start_proxy_call(); // Arguments - write_SDL_Event(*event); + safe_write((void *) event, sizeof (SDL_Event)); // Get Return Value int32_t ret = (int32_t) read_int(); @@ -193,7 +83,8 @@ CALL(2, SDL_PushEvent, int, (SDL_Event *event)) { // Return Value return ret; #else - SDL_Event event = read_SDL_Event(); + SDL_Event event; + safe_read((void *) &event, sizeof (SDL_Event)); // Run int ret = SDL_PushEvent(&event); // Return Value diff --git a/mods/CMakeLists.txt b/mods/CMakeLists.txt index 7b3e4f26..d6e16b06 100644 --- a/mods/CMakeLists.txt +++ b/mods/CMakeLists.txt @@ -54,7 +54,7 @@ else() target_link_libraries(override reborn symbols dl home) add_library(textures SHARED src/textures/textures.cpp) - target_link_libraries(textures reborn symbols feature) + target_link_libraries(textures reborn symbols media-layer-core feature) add_library(atlas SHARED src/atlas/atlas.cpp) target_link_libraries(atlas reborn symbols feature GLESv1_CM) diff --git a/mods/src/atlas/atlas.cpp b/mods/src/atlas/atlas.cpp index a9ffd3de..ab5afd74 100644 --- a/mods/src/atlas/atlas.cpp +++ b/mods/src/atlas/atlas.cpp @@ -15,10 +15,10 @@ static float ItemRenderer_renderGuiItemCorrect_injection(unsigned char *font, un bool use_carried = false; if (item_instance != NULL) { if (item_instance->id == leaves_id) { - (*ItemInstance_constructor_tile_extra)(&carried_item_instance, *Tile_leaves_carried, item_instance->count, item_instance->auxilary); + (*ItemInstance_constructor_tile_extra)(&carried_item_instance, *Tile_leaves_carried, item_instance->count, item_instance->auxiliary); use_carried = true; } else if (item_instance->id == grass_id) { - (*ItemInstance_constructor_tile_extra)(&carried_item_instance, *Tile_grass_carried, item_instance->count, item_instance->auxilary); + (*ItemInstance_constructor_tile_extra)(&carried_item_instance, *Tile_grass_carried, item_instance->count, item_instance->auxiliary); use_carried = true; } } diff --git a/mods/src/chat/chat.cpp b/mods/src/chat/chat.cpp index ed17e872..f086b7e4 100644 --- a/mods/src/chat/chat.cpp +++ b/mods/src/chat/chat.cpp @@ -71,7 +71,7 @@ static void CommandServer_parse_CommandServer_dispatchPacket_injection(unsigned } // Handle ChatPacket Server-Side -static void ServerSideNetworkHandler_handle_ChatPacket_injection(unsigned char *server_side_network_handler, unsigned char *rak_net_guid, unsigned char *chat_packet) { +static void ServerSideNetworkHandler_handle_ChatPacket_injection(unsigned char *server_side_network_handler, RakNet_RakNetGUID *rak_net_guid, unsigned char *chat_packet) { unsigned char *player = (*ServerSideNetworkHandler_getPlayer)(server_side_network_handler, rak_net_guid); if (player != NULL) { char *username = *(char **) (player + Player_username_property_offset); diff --git a/mods/src/creative/creative.cpp b/mods/src/creative/creative.cpp index 8f869ae3..998e592b 100644 --- a/mods/src/creative/creative.cpp +++ b/mods/src/creative/creative.cpp @@ -44,6 +44,9 @@ static int32_t Inventory_setupDefault_FillingContainer_addItem_call_injection(un inventory_add_item(filling_container, *Tile_topSnow, true); inventory_add_item(filling_container, *Tile_ice, true); inventory_add_item(filling_container, *Tile_invisible_bedrock, true); + inventory_add_item(filling_container, *Tile_bedrock, true); + inventory_add_item(filling_container, *Tile_info_updateGame1, true); + inventory_add_item(filling_container, *Tile_info_updateGame2, true); return ret; } diff --git a/mods/src/feature/feature.c b/mods/src/feature/feature.c index 476af7da..fda15dbe 100644 --- a/mods/src/feature/feature.c +++ b/mods/src/feature/feature.c @@ -29,7 +29,7 @@ int feature_has(const char *name, int server_default) { tok = strtok(NULL, "|"); } free(features); -#ifndef MCPI_SERVER_MODE +#ifdef DEBUG INFO("Feature: %s: %s", name, ret ? "Enabled" : "Disabled"); #endif return ret; diff --git a/mods/src/home/home.c b/mods/src/home/home.c index 5edbafb5..f5023095 100644 --- a/mods/src/home/home.c +++ b/mods/src/home/home.c @@ -13,16 +13,13 @@ #define NEW_PATH "" // Store Launch Directory -static char *get_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__((constructor)) static void init_launch_directory() { - get_launch_directory(); -} __attribute__((destructor)) static void free_launch_directory() { free(get_launch_directory()); } diff --git a/mods/src/input/attack.c b/mods/src/input/attack.c index c23c538e..38d4e911 100644 --- a/mods/src/input/attack.c +++ b/mods/src/input/attack.c @@ -33,6 +33,7 @@ static int32_t MouseBuildInput_tickBuild_injection(unsigned char *mouse_build_in is_left_click = 2; } + // Return return ret; } diff --git a/mods/src/input/bow.c b/mods/src/input/bow.c index 80a8f2eb..9313a47b 100644 --- a/mods/src/input/bow.c +++ b/mods/src/input/bow.c @@ -14,7 +14,7 @@ void input_set_is_right_click(int val) { static int fix_bow = 0; // Handle Bow & Arrow -void _handle_bow(unsigned char *minecraft) { +static void _handle_bow(unsigned char *minecraft) { if (fix_bow && !is_right_click) { // GameMode Is Offset From minecraft By 0x160 // Player Is Offset From minecraft By 0x18c @@ -32,4 +32,5 @@ void _handle_bow(unsigned char *minecraft) { void _init_bow() { // Enable Bow & Arrow Fix fix_bow = feature_has("Fix Bow & Arrow", 0); + input_run_on_tick(_handle_bow); } diff --git a/mods/src/input/drop.cpp b/mods/src/input/drop.cpp index 68037228..ef051b34 100644 --- a/mods/src/input/drop.cpp +++ b/mods/src/input/drop.cpp @@ -21,7 +21,7 @@ void input_drop(int drop_slot) { } // Handle Drop Item Presses -void _handle_drop(unsigned char *minecraft) { +static void _handle_drop(unsigned char *minecraft) { if (!(*Minecraft_isCreativeMode)(minecraft) && (drop_item_presses > 0 || drop_slot_pressed)) { // Get Player unsigned char *player = *(unsigned char **) (minecraft + Minecraft_player_property_offset); @@ -85,4 +85,5 @@ void _handle_drop(unsigned char *minecraft) { // Init void _init_drop() { enable_drop = feature_has("Bind \"Q\" Key To Item Dropping", 0); + input_run_on_tick(_handle_drop); } diff --git a/mods/src/input/input.cpp b/mods/src/input/input.cpp index d83b4ca0..7e2e6973 100644 --- a/mods/src/input/input.cpp +++ b/mods/src/input/input.cpp @@ -21,21 +21,6 @@ static void Minecraft_tickInput_injection(unsigned char *minecraft) { // Call Original Method (*Minecraft_tickInput)(minecraft); - // Handle Bow - _handle_bow(minecraft); - - // Handle Toggle Options - _handle_toggle_options(minecraft); - - // Set Mouse Grab State - _handle_mouse_grab(minecraft); - - // Handle Back Button - _handle_back(minecraft); - - // Handle Item Drops - _handle_drop(minecraft); - // Run Input Tick Functions for (input_tick_function_t function : get_input_tick_functions()) { (*function)(minecraft); diff --git a/mods/src/input/input.h b/mods/src/input/input.h index b18b374c..83fe1102 100644 --- a/mods/src/input/input.h +++ b/mods/src/input/input.h @@ -19,14 +19,9 @@ void input_set_mouse_grab_state(int state); __attribute__((visibility("internal"))) void _init_attack(); __attribute__((visibility("internal"))) void _init_bow(); -__attribute__((visibility("internal"))) void _handle_bow(unsigned char *minecraft); -__attribute__((visibility("internal"))) void _handle_toggle_options(unsigned char *minecraft); __attribute__((visibility("internal"))) void _init_misc(); __attribute__((visibility("internal"))) void _init_toggle(); -__attribute__((visibility("internal"))) void _handle_mouse_grab(unsigned char *minecraft); -__attribute__((visibility("internal"))) void _handle_back(unsigned char *minecraft); __attribute__((visibility("internal"))) void _init_drop(); -__attribute__((visibility("internal"))) void _handle_drop(unsigned char *minecraft); #ifdef __cplusplus } diff --git a/mods/src/input/misc.c b/mods/src/input/misc.c index da0a18df..18cfa9c2 100644 --- a/mods/src/input/misc.c +++ b/mods/src/input/misc.c @@ -19,7 +19,7 @@ int input_back() { } // Handle Back Button Presses -void _handle_back(unsigned char *minecraft) { +static void _handle_back(unsigned char *minecraft) { unsigned char *minecraft_vtable = *(unsigned char **) minecraft; Minecraft_handleBack_t Minecraft_handleBack = *(Minecraft_handleBack_t *) (minecraft_vtable + Minecraft_handleBack_vtable_offset); for (int i = 0; i < back_button_presses; i++) { @@ -44,7 +44,7 @@ void input_set_mouse_grab_state(int state) { } // Grab/Un-Grab Mouse -void _handle_mouse_grab(unsigned char *minecraft) { +static void _handle_mouse_grab(unsigned char *minecraft) { if (mouse_grab_state == -1) { // Grab (*Minecraft_grabMouse)(minecraft); @@ -88,4 +88,6 @@ void _init_misc() { // Disable Opening Inventory Using The Cursor When Cursor Is Hidden overwrite_calls((void *) Gui_handleClick, (void *) Gui_handleClick_injection); } + input_run_on_tick(_handle_back); + input_run_on_tick(_handle_mouse_grab); } diff --git a/mods/src/input/toggle.c b/mods/src/input/toggle.c index 2b8f7e69..1b68e9a9 100644 --- a/mods/src/input/toggle.c +++ b/mods/src/input/toggle.c @@ -18,7 +18,7 @@ void input_third_person() { } // Handle Toggle Options -void _handle_toggle_options(unsigned char *minecraft) { +static void _handle_toggle_options(unsigned char *minecraft) { if (enable_toggles) { // Handle Functions unsigned char *options = minecraft + Minecraft_options_property_offset; @@ -38,4 +38,5 @@ void _handle_toggle_options(unsigned char *minecraft) { // Init void _init_toggle() { enable_toggles = feature_has("Bind Common Toggleable Options To Function Keys", 0); + input_run_on_tick(_handle_toggle_options); } diff --git a/mods/src/options/options.c b/mods/src/options/options.c index 6c108e36..e6cddabc 100644 --- a/mods/src/options/options.c +++ b/mods/src/options/options.c @@ -100,20 +100,22 @@ void init_options() { } patch_address((void *) default_username, (void *) username); + // Disable Autojump By Default if (feature_has("Disable Autojump By Default", 0)) { - // Disable Autojump By Default unsigned char autojump_patch[4] = {0x00, 0x30, 0xa0, 0xe3}; // "mov r3, #0x0" patch((void *) 0x44b90, autojump_patch); } + // Display Nametags By Default if (feature_has("Display Nametags By Default", 0)) { - // Display Nametags By Default + // r6 = 0x1 + // r5 = 0x0 unsigned char display_nametags_patch[4] = {0x1d, 0x60, 0xc0, 0xe5}; // "strb r6, [r0, #0x1d]" patch((void *) 0xa6628, display_nametags_patch); } + // Enable Smooth Lighting smooth_lighting = feature_has("Smooth Lighting", 0); if (smooth_lighting) { - // Enable Smooth Lighting unsigned char smooth_lighting_patch[4] = {0x01, 0x00, 0x53, 0xe3}; // "cmp r3, #0x1" patch((void *) 0x59ea4, smooth_lighting_patch); } diff --git a/mods/src/server/server.cpp b/mods/src/server/server.cpp index a748c575..ba898f95 100644 --- a/mods/src/server/server.cpp +++ b/mods/src/server/server.cpp @@ -198,16 +198,20 @@ static unsigned char *get_rak_peer(unsigned char *minecraft) { unsigned char *rak_net_instance = *(unsigned char **) (minecraft + Minecraft_rak_net_instance_property_offset); return *(unsigned char **) (rak_net_instance + RakNetInstance_peer_property_offset); } - -// Get IP From Player -static char *get_player_ip(unsigned char *minecraft, unsigned char *player) { - RakNet_RakNetGUID guid = get_rak_net_guid(player); - unsigned char *rak_peer = get_rak_peer(minecraft); +static char *get_rak_net_guid_ip(unsigned char *rak_peer, RakNet_RakNetGUID guid) { RakNet_SystemAddress address = get_system_address(rak_peer, guid); // Get IP return (*RakNet_SystemAddress_ToString)(&address, false, '|'); } +// Get IP From Player +static char *get_player_ip(unsigned char *minecraft, unsigned char *player) { + unsigned char *rak_peer = get_rak_peer(minecraft); + RakNet_RakNetGUID guid = get_rak_net_guid(player); + // Return + return get_rak_net_guid_ip(rak_peer,guid); +} + // Ban Player static void ban_callback(unsigned char *minecraft, std::string username, unsigned char *player) { // Get IP @@ -275,25 +279,33 @@ static unsigned char *get_server_side_network_handler(unsigned char *minecraft) static volatile bool stdin_buffer_complete = false; static volatile char *stdin_buffer = NULL; static void *read_stdin_thread(__attribute__((unused)) void *data) { - while (1) { - if (!stdin_buffer_complete) { - int x = getchar(); - if (x != EOF) { - if (x == '\n') { - if (stdin_buffer == NULL) { - stdin_buffer = strdup(""); + // Check If STDIN Is A TTY + if (isatty(fileno(stdin))) { + // Loop + while (1) { + if (!stdin_buffer_complete) { + // Read Data + int x = fgetc(stdin); + if (x != EOF) { + if (x == '\n') { + if (stdin_buffer == NULL) { + stdin_buffer = strdup(""); + } + stdin_buffer_complete = true; + } else { + string_append((char **) &stdin_buffer, "%c", (char) x); } - stdin_buffer_complete = true; - } else { - string_append((char **) &stdin_buffer, "%c", (char) x); } } } } + return NULL; } __attribute__((destructor)) static void _free_stdin_buffer() { - free((void *) stdin_buffer); - stdin_buffer = NULL; + if (stdin_buffer != NULL) { + free((void *) stdin_buffer); + stdin_buffer = NULL; + } } // Handle Commands @@ -385,6 +397,7 @@ static void Minecraft_update_injection(unsigned char *minecraft) { handle_server_stop(minecraft); } +// Ban Players static bool RakNet_RakPeer_IsBanned_injection(__attribute__((unused)) unsigned char *rakpeer, const char *ip) { // Check banned-ips.txt std::string blacklist_file_path = get_blacklist_file(); @@ -420,6 +433,27 @@ static bool RakNet_RakPeer_IsBanned_injection(__attribute__((unused)) unsigned c } } +// Log IPs +static unsigned char *ServerSideNetworkHandler_onReady_ClientGeneration_ServerSideNetworkHandler_popPendingPlayer_injection(unsigned char *server_side_network_handler, RakNet_RakNetGUID *guid) { + // Call Original Method + unsigned char *player = (*ServerSideNetworkHandler_popPendingPlayer)(server_side_network_handler, guid); + + // Check If Player Is Null + if (player != NULL) { + // Get Data + char *username = (char *) *(unsigned char **) (player + Player_username_property_offset); + unsigned char *minecraft = *(unsigned char **) (server_side_network_handler + ServerSideNetworkHandler_minecraft_property_offset); + unsigned char *rak_peer = get_rak_peer(minecraft); + char *ip = get_rak_net_guid_ip(rak_peer, *guid); + + // Log + INFO("%s Has Joined (IP: %s)", username, ip); + } + + // Return + return player; +} + // Get MOTD static std::string get_motd() { std::string motd(get_server_properties().get_string("motd", DEFAULT_MOTD)); @@ -532,6 +566,9 @@ static void server_init() { patch((void *) 0x737e4, minecon_badge_patch); } + // Log IPs + overwrite_call((void *) 0x75e54, (void *) ServerSideNetworkHandler_onReady_ClientGeneration_ServerSideNetworkHandler_popPendingPlayer_injection); + // Start Reading STDIN pthread_t read_stdin_thread_obj; pthread_create(&read_stdin_thread_obj, NULL, read_stdin_thread, NULL); diff --git a/mods/src/textures/textures.cpp b/mods/src/textures/textures.cpp index 450e2e90..641d4cec 100644 --- a/mods/src/textures/textures.cpp +++ b/mods/src/textures/textures.cpp @@ -1,3 +1,9 @@ +#include +#include +#include + +#include + #include #include @@ -16,10 +22,154 @@ static void Minecraft_tick_injection(unsigned char *minecraft, int32_t param_1, } } +// Store Texture Sizes +struct texture_data { + GLint id; + GLsizei width; + GLsizei height; +}; +static std::vector &get_texture_data() { + static std::vector data; + return data; +} +HOOK(glTexImage2D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)) { + // Store + texture_data data; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &data.id); + data.width = width; + data.height = height; + get_texture_data().push_back(data); + + // Call Original Method + ensure_glTexImage2D(); + (*real_glTexImage2D)(target, level, internalformat, width, height, border, format, type, pixels); +} +HOOK(glDeleteTextures, void, (GLsizei n, const GLuint *textures)) { + // Remove Old Data + for (int i = 0; i < n; i++) { + GLint id = textures[i]; + std::vector::iterator it = get_texture_data().begin(); + while (it != get_texture_data().end()) { + texture_data data = *it; + if (data.id == id) { + it = get_texture_data().erase(it); + } else { + ++it; + } + } + } + + // Call Original Method + ensure_glDeleteTextures(); + (*real_glDeleteTextures)(n, textures); +} +static void get_texture_size(GLint id, GLsizei *width, GLsizei *height) { + // Iterate + std::vector::iterator it = get_texture_data().begin(); + while (it != get_texture_data().end()) { + texture_data data = *it; + if (data.id == id) { + // Found + *width = data.width; + *height = data.height; + return; + } + ++it; + } + // Not Found + ERR("Unable To Find Size Of Texture: %i", id); +} + +// Scale Texture (Remember To Free) +#define PIXEL_SIZE 4 +static int get_line_size(int width) { + int line_size = width * PIXEL_SIZE; + { + // Handle Alignment + int alignment; + glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); + // Round + int diff = line_size % alignment; + if (diff > 0) { + line_size = line_size + (alignment - diff); + } + } + return line_size; +} +static void *scale_texture(const unsigned char *src, GLsizei old_width, GLsizei old_height, GLsizei new_width, GLsizei new_height) { + int old_line_size = get_line_size(old_width); + int new_line_size = get_line_size(new_width); + + // Allocate + unsigned char *dst = (unsigned char *) malloc(new_height * new_line_size); + ALLOC_CHECK(dst); + + // Scale + for (int new_x = 0; new_x < new_width; new_x++) { + int old_x = (int) (((float) new_x / (float) new_width) * (float) old_width); + for (int new_y = 0; new_y < new_height; new_y++) { + int old_y = (int) (((float) new_y / (float) new_height) * (float) old_height); + + // Find Position + int new_position = (new_y * new_line_size) + (new_x * PIXEL_SIZE); + int old_position = (old_y * old_line_size) + (old_x * PIXEL_SIZE); + + // Copy + static_assert(sizeof (int32_t) == PIXEL_SIZE, "Pixel Size Doesn't Match 32-Bit Integer Size"); + *(int32_t *) &dst[new_position] = *(int32_t *) &src[old_position]; + } + } + + // Return + return dst; +} + +// Scale Animated Textures +static void Textures_tick_glTexSubImage2D_injection(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) { + // Get Current Texture Size + GLint current_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); + GLsizei texture_width; + GLsizei texture_height; + get_texture_size(current_texture, &texture_width, &texture_height); + + // Calculate Factor + float width_factor = ((float) texture_width) / 256.0f; + float height_factor = ((float) texture_height) / 256.0f; + + // Only Scale If Needed + if (width_factor == 1.0f && height_factor == 1.0f) { + // No Scaling + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + } else { + // Check + if (format != GL_RGBA || type != GL_UNSIGNED_BYTE) { + // Pixels Must Be 4 Bytes + ERR("%s", "Unsupported Texture Format For Scaling"); + } + + // Scale + GLsizei new_width = width * width_factor; + GLsizei new_height = height * height_factor; + void *new_pixels = scale_texture((const unsigned char *) pixels, width, height, new_width, new_height); + + // Call Original Method + GLint new_xoffset = xoffset * width_factor; + GLint new_yoffset = yoffset * height_factor; + glTexSubImage2D(target, level, new_xoffset, new_yoffset, new_width, new_height, format, type, new_pixels); + + // Free + free(new_pixels); + } +} + // Init void init_textures() { // Tick Dynamic Textures (Animated Water) if (feature_has("Animated Water", 0)) { overwrite_calls((void *) Minecraft_tick, (void *) Minecraft_tick_injection); } + + // Scale Animated Textures + overwrite_call((void *) 0x53274, (void *) Textures_tick_glTexSubImage2D_injection); } diff --git a/scripts/build-all.sh b/scripts/build-all.sh index aa60a372..674d780e 100755 --- a/scripts/build-all.sh +++ b/scripts/build-all.sh @@ -6,9 +6,9 @@ set -e rm -rf out # Build -./scripts/build.sh client x86_64 -./scripts/build.sh server x86_64 +./scripts/build.sh client amd64 +./scripts/build.sh server amd64 ./scripts/build.sh client arm64 ./scripts/build.sh server arm64 -./scripts/build.sh client arm -./scripts/build.sh server arm +./scripts/build.sh client armhf +./scripts/build.sh server armhf diff --git a/scripts/build.sh b/scripts/build.sh index 031baca9..d74155b5 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -48,14 +48,14 @@ build() { } # Build For ARM -arm_build() { +armhf_build() { # Create Build Dir - rm -rf "build/$1-arm" - mkdir -p "build/$1-arm" - cd "build/$1-arm" + rm -rf "build/$1-armhf" + mkdir -p "build/$1-armhf" + cd "build/$1-armhf" # Create Prefix - local prefix="$(cd ../../; pwd)/out/$1-arm" + local prefix="$(cd ../../; pwd)/out/$1-armhf" rm -rf "${prefix}" mkdir -p "${prefix}" @@ -81,8 +81,8 @@ if [ "$1" != "client" ] && [ "$1" != "server" ]; then fi # Build -if [ "$2" = "arm" ]; then - arm_build "$1" +if [ "$2" = "armhf" ]; then + armhf_build "$1" else build "$1" "$2" fi diff --git a/scripts/install-dependencies.sh b/scripts/install-dependencies.sh index 003b86f4..9f2f8c5d 100755 --- a/scripts/install-dependencies.sh +++ b/scripts/install-dependencies.sh @@ -22,6 +22,7 @@ sudo apt-get dist-upgrade -y sudo apt-get install --no-install-recommends -y \ ca-certificates \ lsb-release \ + dpkg-dev \ git \ clang \ lld \ @@ -30,7 +31,7 @@ sudo apt-get install --no-install-recommends -y \ libglfw3 libglfw3-dev \ libfreeimage3 libfreeimage-dev \ crossbuild-essential-armhf \ - crossbuild-essential-arm64 \ + gcc g++ \ libopenal-dev \ qemu-user-static @@ -42,6 +43,7 @@ if [ ! -z "${ARM_PACKAGES_SUPPORTED}" ]; then libopenal-dev:armhf \ libglfw3:arm64 libglfw3-dev:arm64 \ libfreeimage3:arm64 \ - libopenal-dev:arm64 + libopenal-dev:arm64 \ + crossbuild-essential-arm64 fi diff --git a/scripts/test.sh b/scripts/test.sh index d5c7cbe9..75407580 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -3,7 +3,7 @@ set -e # Add minecraft-pi-reborn-server To PATH -export PATH="$(pwd)/out/server-x86_64/usr/bin:${PATH}" +export PATH="$(pwd)/out/server-$(dpkg-architecture -qDEB_BUILD_ARCH)/usr/bin:${PATH}" # Create Test Directory rm -rf build/test diff --git a/symbols/include/symbols/minecraft.h b/symbols/include/symbols/minecraft.h index 2c897298..8673ffb5 100644 --- a/symbols/include/symbols/minecraft.h +++ b/symbols/include/symbols/minecraft.h @@ -19,37 +19,49 @@ static char **default_path = (char **) 0xe264; // /.minecraft/ static char **default_username = (char **) 0x18fd4; // StevePi static char **minecraft_pi_version = (char **) 0x39d94; // v0.1.1 alpha -static unsigned char **Item_flintAndSteel = (unsigned char **) 0x17ba70; -static unsigned char **Item_snowball = (unsigned char **) 0x17bbb0; -static unsigned char **Item_shears = (unsigned char **) 0x17bbf0; -static unsigned char **Item_egg = (unsigned char **) 0x17bbd0; -static unsigned char **Item_dye_powder = (unsigned char **) 0x17bbe0; -static unsigned char **Item_camera = (unsigned char **) 0x17bc14; +static unsigned char **Material_stone = (unsigned char **) 0x180a9c; // Material -static unsigned char **Tile_water = (unsigned char **) 0x181b3c; -static unsigned char **Tile_lava = (unsigned char **) 0x181cc8; -static unsigned char **Tile_calmWater = (unsigned char **) 0x181b40; -static unsigned char **Tile_calmLava = (unsigned char **) 0x181ccc; -static unsigned char **Tile_glowingObsidian = (unsigned char **) 0x181dcc; -static unsigned char **Tile_web = (unsigned char **) 0x181d08; -static unsigned char **Tile_topSnow = (unsigned char **) 0x181b30; -static unsigned char **Tile_ice = (unsigned char **) 0x181d80; -static unsigned char **Tile_invisible_bedrock = (unsigned char **) 0x181d94; -static unsigned char **Tile_netherReactor = (unsigned char **) 0x181dd0; +static unsigned char *SOUND_STONE = (unsigned char *) 0x181c80; // Tile::SoundType -static unsigned char **Tile_leaves = (unsigned char **) 0x18120c; -static unsigned char **Tile_leaves_carried = (unsigned char **) 0x181dd8; -static unsigned char **Tile_grass = (unsigned char **) 0x181b14; -static unsigned char **Tile_grass_carried = (unsigned char **) 0x181dd4; +static unsigned char **Item_flintAndSteel = (unsigned char **) 0x17ba70; // Item +static unsigned char **Item_snowball = (unsigned char **) 0x17bbb0; // Item +static unsigned char **Item_shears = (unsigned char **) 0x17bbf0; // Item +static unsigned char **Item_egg = (unsigned char **) 0x17bbd0; // Item +static unsigned char **Item_dye_powder = (unsigned char **) 0x17bbe0; // Item +static unsigned char **Item_camera = (unsigned char **) 0x17bc14; // Item + +static unsigned char **Tile_water = (unsigned char **) 0x181b3c; // Tile +static unsigned char **Tile_lava = (unsigned char **) 0x181cc8; // Tile +static unsigned char **Tile_calmWater = (unsigned char **) 0x181b40; // Tile +static unsigned char **Tile_calmLava = (unsigned char **) 0x181ccc; // Tile +static unsigned char **Tile_glowingObsidian = (unsigned char **) 0x181dcc; // Tile +static unsigned char **Tile_web = (unsigned char **) 0x181d08; // Tile +static unsigned char **Tile_topSnow = (unsigned char **) 0x181b30; // Tile +static unsigned char **Tile_ice = (unsigned char **) 0x181d80; // Tile +static unsigned char **Tile_invisible_bedrock = (unsigned char **) 0x181d94; // Tile +static unsigned char **Tile_netherReactor = (unsigned char **) 0x181dd0; // Tile +static unsigned char **Tile_info_updateGame1 = (unsigned char **) 0x181c68; // Tile +static unsigned char **Tile_info_updateGame2 = (unsigned char **) 0x181c6c; // Tile +static unsigned char **Tile_bedrock = (unsigned char **) 0x181cc4; // Tile + +static unsigned char **Tile_leaves = (unsigned char **) 0x18120c; // Tile +static unsigned char **Tile_leaves_carried = (unsigned char **) 0x181dd8; // Tile +static unsigned char **Tile_grass = (unsigned char **) 0x181b14; // Tile +static unsigned char **Tile_grass_carried = (unsigned char **) 0x181dd4; // Tile static float *InvGuiScale = (float *) 0x135d98; -// Tile - -static uint32_t Tile_id_property_offset = 0x8; - // Structures +struct AABB { + float x1; + float y1; + float z1; + float x2; + float y2; + float z2; +}; + struct LevelSettings { unsigned long seed; int32_t game_type; @@ -62,6 +74,37 @@ struct RakNet_SystemAddress { unsigned char data[20]; }; +// Tile + +typedef void (*Tile_initTiles_t)(); +static Tile_initTiles_t Tile_initTiles = (Tile_initTiles_t) 0xc358c; + +#define TILE_SIZE 0x5c +#define TILE_VTABLE_SIZE 0x104 + +static unsigned char *Tile_vtable = (unsigned char *) 0x115670; + +typedef unsigned char *(*Tile_t)(unsigned char *tile, int32_t id, int32_t texture, const void *material); +static Tile_t Tile = (Tile_t) 0xc33a0; + +typedef unsigned char *(*Tile_init_t)(unsigned char *tile); +static Tile_init_t Tile_init = (Tile_init_t) 0xc34dc; + +typedef unsigned char *(*Tile_setDestroyTime_t)(unsigned char *tile, float destroy_time); +static uint32_t Tile_setDestroyTime_vtable_offset = 0xf8; + +typedef unsigned char *(*Tile_setExplodeable_t)(unsigned char *tile, float explodeable); +static uint32_t Tile_setExplodeable_vtable_offset = 0xf4; + +typedef unsigned char *(*Tile_setSoundType_t)(unsigned char *tile, unsigned char *sound_type); +static uint32_t Tile_setSoundType_vtable_offset = 0xe8; + +typedef int32_t (*Tile_use_t)(unsigned char *tile, unsigned char *level, int32_t x, int32_t y, int32_t z, unsigned char *player); +static uint32_t Tile_use_vtable_offset = 0x98; + +static uint32_t Tile_id_property_offset = 0x8; // int32_t +static uint32_t Tile_category_property_offset = 0x3c; // int32_t + // GameMode typedef void (*GameMode_releaseUsingItem_t)(unsigned char *game_mode, unsigned char *player); @@ -130,6 +173,8 @@ static uint32_t Minecraft_progress_property_offset = 0xc60; // int32_t static uint32_t Minecraft_command_server_property_offset = 0xcc0; // CommandServer * static uint32_t Minecraft_screen_property_offset = 0xc10; // Screen * static uint32_t Minecraft_gui_property_offset = 0x198; // Gui +static uint32_t Minecraft_pov_property_offset = 0x150; // Mob * +static uint32_t Minecraft_perf_renderer_property_offset = 0xcbc; // PerfRenderer * // GameRenderer @@ -194,6 +239,7 @@ static uint32_t Options_hide_gui_property_offset = 0xec; // unsigned char / bool static uint32_t Options_third_person_property_offset = 0xed; // unsigned char / bool 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 // MouseBuildInput @@ -206,14 +252,14 @@ static void *MouseBuildInput_tickBuild_vtable_addr = (void *) 0x102564; typedef struct { int32_t count; int32_t id; - int32_t auxilary; + int32_t auxiliary; } ItemInstance; typedef ItemInstance *(*ItemInstance_constructor_t)(ItemInstance *item_instance, unsigned char *item); static ItemInstance_constructor_t ItemInstance_constructor_item = (ItemInstance_constructor_t) 0x9992c; static ItemInstance_constructor_t ItemInstance_constructor_tile = (ItemInstance_constructor_t) 0x998e4; -typedef ItemInstance *(*ItemInstance_constructor_extra_t)(ItemInstance *item_instance, unsigned char *item, int32_t count, int32_t auxilary); +typedef ItemInstance *(*ItemInstance_constructor_extra_t)(ItemInstance *item_instance, unsigned char *item, int32_t count, int32_t auxiliary); static ItemInstance_constructor_extra_t ItemInstance_constructor_tile_extra = (ItemInstance_constructor_extra_t) 0x99918; static ItemInstance_constructor_extra_t ItemInstance_constructor_item_extra = (ItemInstance_constructor_extra_t) 0x99960; @@ -249,7 +295,7 @@ static Player_isUsingItem_t Player_isUsingItem = (Player_isUsingItem_t) 0x8f15c; typedef void (*Player_drop_t)(unsigned char *player, ItemInstance *item_instance, bool is_death); static uint32_t Player_drop_vtable_offset = 0x208; -static Mob_getWalkingSpeedModifier_t Player_getWalkingSpeed = (Mob_getWalkingSpeedModifier_t) 0x8ea0c; +static Mob_getWalkingSpeedModifier_t Player_getWalkingSpeedModifier = (Mob_getWalkingSpeedModifier_t) 0x8ea0c; static uint32_t Player_username_property_offset = 0xbf4; // char * static uint32_t Player_inventory_property_offset = 0xbe0; // Inventory * @@ -309,8 +355,26 @@ static LevelData_getSpawnMobs_t LevelData_getSpawnMobs = (LevelData_getSpawnMobs typedef void (*Level_saveLevelData_t)(unsigned char *level); static Level_saveLevelData_t Level_saveLevelData = (Level_saveLevelData_t) 0xa2e94; +typedef void (*Level_setTileAndData_t)(unsigned char *level, int32_t x, int32_t y, int32_t z, int32_t id, int32_t data); +static Level_setTileAndData_t Level_setTileAndData = (Level_setTileAndData_t) 0xa38b4; + static uint32_t Level_players_property_offset = 0x60; // std::vector +// LevelRenderer + +typedef void (*LevelRenderer_render_t)(unsigned char *level_renderer, unsigned char *mob, int param_1, float delta); +static LevelRenderer_render_t LevelRenderer_render = (LevelRenderer_render_t) 0x4f710; + +typedef void (*LevelRenderer_renderDebug_t)(unsigned char *level_renderer, struct AABB *aabb, float delta); +static LevelRenderer_renderDebug_t LevelRenderer_renderDebug = (LevelRenderer_renderDebug_t) 0x4d310; + +static uint32_t LevelRenderer_minecraft_property_offset = 0x4; // Minecraft * + +// PerfRenderer + +typedef void (*PerfRenderer_debugFpsMeterKeyPress_t)(unsigned char *perf_renderer, int key); +static PerfRenderer_debugFpsMeterKeyPress_t PerfRenderer_debugFpsMeterKeyPress = (PerfRenderer_debugFpsMeterKeyPress_t) 0x79118; + // TextEditScreen #define TEXT_EDIT_SCREEN_SIZE 0xd0 @@ -456,17 +520,22 @@ static RakNet_SystemAddress_ToString_t RakNet_SystemAddress_ToString = (RakNet_S // ServerSideNetworkHandler -typedef void (*ServerSideNetworkHandler_onDisconnect_t)(unsigned char *server_side_network_handler, unsigned char *guid); +typedef void (*ServerSideNetworkHandler_onDisconnect_t)(unsigned char *server_side_network_handler, struct RakNet_RakNetGUID *guid); static ServerSideNetworkHandler_onDisconnect_t ServerSideNetworkHandler_onDisconnect = (ServerSideNetworkHandler_onDisconnect_t) 0x75164; static void *ServerSideNetworkHandler_onDisconnect_vtable_addr = (void *) 0x109bb0; -typedef unsigned char *(*ServerSideNetworkHandler_getPlayer_t)(unsigned char *server_side_network_handler, unsigned char *guid); +typedef unsigned char *(*ServerSideNetworkHandler_getPlayer_t)(unsigned char *server_side_network_handler, struct RakNet_RakNetGUID *guid); static ServerSideNetworkHandler_getPlayer_t ServerSideNetworkHandler_getPlayer = (ServerSideNetworkHandler_getPlayer_t) 0x75464; -typedef void (*ServerSideNetworkHandler_handle_t)(unsigned char *server_side_network_handler, unsigned char *rak_net_guid, unsigned char *packet); +typedef unsigned char *(*ServerSideNetworkHandler_popPendingPlayer_t)(unsigned char *server_side_network_handler, struct RakNet_RakNetGUID *guid); +static ServerSideNetworkHandler_popPendingPlayer_t ServerSideNetworkHandler_popPendingPlayer = (ServerSideNetworkHandler_popPendingPlayer_t) 0x75db4; + +typedef void (*ServerSideNetworkHandler_handle_t)(unsigned char *server_side_network_handler, struct RakNet_RakNetGUID *rak_net_guid, unsigned char *packet); static void *ServerSideNetworkHandler_handle_ChatPacket_vtable_addr = (void *) 0x109c60; +static uint32_t ServerSideNetworkHandler_minecraft_property_offset = 0x8; // Minecraft * + // Inventory typedef void (*Inventory_selectSlot_t)(unsigned char *inventory, int32_t slot); @@ -544,6 +613,11 @@ struct ConnectedClient { long time; }; +// Tile + +typedef unsigned char *(*Tile_setDescriptionId_t)(unsigned char *tile, std::string const& description_id); +static uint32_t Tile_setDescriptionId_vtable_offset = 0xe0; + // AppPlatform typedef void (*AppPlatform_saveScreenshot_t)(unsigned char *app_platform, std::string const& path, int32_t width, int32_t height);