WIP New Modding API

This commit is contained in:
TheBrokenRail 2024-01-06 06:30:23 -05:00
parent 0be1f4fce8
commit aa92da6fdd
161 changed files with 1423 additions and 1763 deletions

3
.gitmodules vendored
View File

@ -19,3 +19,6 @@
[submodule "archives"] [submodule "archives"]
path = archives path = archives
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/archives.git url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/archives.git
[submodule "dependencies/symbol-processor/src"]
path = dependencies/symbol-processor/src
url = https://gitea.thebrokenrail.com/minecraft-pi-reborn/symbol-processor.git

View File

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

View File

@ -30,3 +30,7 @@ if(BUILD_MEDIA_LAYER_CORE AND NOT MCPI_HEADLESS_MODE AND MCPI_USE_GLES1_COMPATIB
endif() endif()
# UTF8-CPP # UTF8-CPP
add_subdirectory(utf8cpp) add_subdirectory(utf8cpp)
# Symbol Prcoessor
if(BUILD_ARM_COMPONENTS)
add_subdirectory(symbol-processor)
endif()

View File

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

1
dependencies/symbol-processor/src vendored Submodule

@ -0,0 +1 @@
Subproject commit 1062e048c493607b7b57faf83570562fa44c0f9c

View File

@ -8,6 +8,7 @@ target_include_directories(
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/mods>" "$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/mods>"
) )
target_link_libraries(mods-headers INTERFACE symbols)
# SDK # SDK
install(TARGETS mods-headers EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}") install(TARGETS mods-headers EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
install(DIRECTORY "include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/mods") install(DIRECTORY "include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/mods")
@ -115,7 +116,7 @@ add_library(test SHARED src/test/test.c)
target_link_libraries(test mods-headers reborn-patch home) target_link_libraries(test mods-headers reborn-patch home)
add_library(init SHARED src/init/init.c) add_library(init SHARED src/init/init.c)
target_link_libraries(init mods-headers reborn-util compat game-mode misc death options chat creative bucket textures home version test media-layer-core) target_link_libraries(init symbols mods-headers reborn-util compat game-mode misc death options chat creative bucket textures home version test media-layer-core)
if(MCPI_SERVER_MODE) if(MCPI_SERVER_MODE)
target_link_libraries(init server) target_link_libraries(init server)
else() else()

View File

@ -1,11 +1,12 @@
#pragma once #pragma once
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#include <symbols/minecraft.h>
#ifdef __cplusplus #ifdef __cplusplus
#include <string> #include <string>
// Send API Command // Send API Command
std::string chat_send_api_command(unsigned char *minecraft, char *str); std::string chat_send_api_command(Minecraft *minecraft, std::string str);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -18,8 +19,8 @@ unsigned int chat_get_counter();
#endif #endif
// Override using the HOOK() macro to provide customized chat behavior. // Override using the HOOK() macro to provide customized chat behavior.
void chat_send_message(unsigned char *server_side_network_handler, char *username, char *message); void chat_send_message(ServerSideNetworkHandler *server_side_network_handler, char *username, char *message);
void chat_handle_packet_send(unsigned char *minecraft, unsigned char *packet); void chat_handle_packet_send(Minecraft *minecraft, ChatPacket *packet);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,10 +1,12 @@
#pragma once #pragma once
#include <symbols/minecraft.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef void (*input_tick_function_t)(unsigned char *minecraft); typedef void (*input_tick_function_t)(Minecraft *minecraft);
void input_run_on_tick(input_tick_function_t function); void input_run_on_tick(input_tick_function_t function);
void input_set_is_right_click(int val); void input_set_is_right_click(int val);

View File

@ -2,25 +2,31 @@
#include <stdint.h> #include <stdint.h>
#include <symbols/minecraft.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
int32_t misc_get_real_selected_slot(unsigned char *player); int32_t misc_get_real_selected_slot(Player *player);
typedef void (*misc_update_function_t)(unsigned char *obj); typedef void (*misc_update_function_Minecraft_t)(Minecraft *obj);
void misc_run_on_update(misc_update_function_t function); // obj == Minecraft * void misc_run_on_update(misc_update_function_Minecraft_t function); // obj == Minecraft *
void misc_run_on_tick(misc_update_function_t function); // obj == Minecraft * void misc_run_on_tick(misc_update_function_Minecraft_t function); // obj == Minecraft *
void misc_run_on_recipes_setup(misc_update_function_t function); // obj == Recipes * typedef void (*misc_update_function_Recipes_t)(Recipes *obj);
void misc_run_on_furnace_recipes_setup(misc_update_function_t function); // obj == FurnaceRecipes * void misc_run_on_recipes_setup(misc_update_function_Recipes_t function); // obj == Recipes *
void misc_run_on_creative_inventory_setup(misc_update_function_t function); // obj == FillingContainer * typedef void (*misc_update_function_FurnaceRecipes_t)(FurnaceRecipes *obj);
void misc_run_on_tiles_setup(misc_update_function_t function); // obj == NULL void misc_run_on_furnace_recipes_setup(misc_update_function_FurnaceRecipes_t function); // obj == FurnaceRecipes *
void misc_run_on_items_setup(misc_update_function_t function); // obj == NULL typedef void (*misc_update_function_FillingContainer_t)(FillingContainer *obj);
void misc_run_on_creative_inventory_setup(misc_update_function_FillingContainer_t function); // obj == FillingContainer *
typedef void (*misc_update_function_void_t)(void *obj);
void misc_run_on_tiles_setup(misc_update_function_void_t function); // obj == NULL
void misc_run_on_items_setup(misc_update_function_void_t function); // obj == NULL
void Level_saveLevelData_injection(unsigned char *level); void Level_saveLevelData_injection(Level *level);
// Use this instead of directly calling Gui::addMessage(), it has proper logging! // Use this instead of directly calling Gui::addMessage(), it has proper logging!
void misc_add_message(unsigned char *gui, const char *text); void misc_add_message(Gui *gui, const char *text);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -7,9 +7,9 @@
#include <mods/init/init.h> #include <mods/init/init.h>
// Fix Grass And Leaves Inventory Rendering When The gui_blocks Atlas Is Disabled // Fix Grass And Leaves Inventory Rendering When The gui_blocks Atlas Is Disabled
static void ItemRenderer_renderGuiItemCorrect_injection(unsigned char *font, unsigned char *textures, ItemInstance *item_instance, int32_t param_1, int32_t param_2) { static void ItemRenderer_renderGuiItemCorrect_injection(Font *font, Textures *textures, ItemInstance *item_instance, int32_t param_1, int32_t param_2) {
int32_t leaves_id = *(int32_t *) (*Tile_leaves + Tile_id_property_offset); int32_t leaves_id = (*Tile_leaves)->id;
int32_t grass_id = *(int32_t *) (*Tile_grass + Tile_id_property_offset); int32_t grass_id = (*Tile_grass)->id;
// Replace Rendered Item With Carried Variant // Replace Rendered Item With Carried Variant
ItemInstance carried_item_instance; ItemInstance carried_item_instance;
bool use_carried = false; bool use_carried = false;
@ -40,7 +40,7 @@ static void ItemRenderer_renderGuiItemCorrect_injection(unsigned char *font, uns
static int item_color_fix_mode = 0; static int item_color_fix_mode = 0;
#define POTENTIAL_FURNACE_ITEM_TRANSPARENCY 0x33 #define POTENTIAL_FURNACE_ITEM_TRANSPARENCY 0x33
#define INVALID_FURNACE_ITEM_MULTIPLIER 0.25f #define INVALID_FURNACE_ITEM_MULTIPLIER 0.25f
static void Tesselator_color_injection(unsigned char *tesselator, int32_t r, int32_t g, int32_t b, int32_t a) { static void Tesselator_color_injection(Tesselator *tesselator, int32_t r, int32_t g, int32_t b, int32_t a) {
// Fix Furnace UI // Fix Furnace UI
if (item_color_fix_mode != 0) { if (item_color_fix_mode != 0) {
// Force Translucent // Force Translucent
@ -57,7 +57,7 @@ static void Tesselator_color_injection(unsigned char *tesselator, int32_t r, int
// Call Original Method // Call Original Method
(*Tesselator_color)(tesselator, r, g, b, a); (*Tesselator_color)(tesselator, r, g, b, a);
} }
static void Tesselator_begin_injection(unsigned char *tesselator, int32_t mode) { static void Tesselator_begin_injection(Tesselator *tesselator, int32_t mode) {
// Call Original Method // Call Original Method
(*Tesselator_begin)(tesselator, mode); (*Tesselator_begin)(tesselator, mode);
@ -67,21 +67,21 @@ static void Tesselator_begin_injection(unsigned char *tesselator, int32_t mode)
(*Tesselator_color_injection)(tesselator, 0xff, 0xff, 0xff, 0xff); (*Tesselator_color_injection)(tesselator, 0xff, 0xff, 0xff, 0xff);
} }
} }
static void InventoryPane_renderBatch_Tesselator_color_injection(unsigned char *tesselator, int32_t r, int32_t g, int32_t b) { static void InventoryPane_renderBatch_Tesselator_color_injection(Tesselator *tesselator, int32_t r, int32_t g, int32_t b) {
// Call Original Method // Call Original Method
(*Tesselator_color)(tesselator, r, g, b, 0xff); (*Tesselator_color)(tesselator, r, g, b, 0xff);
// Enable Item Color Fix // Enable Item Color Fix
item_color_fix_mode = 2; item_color_fix_mode = 2;
} }
static void ItemRenderer_renderGuiItem_two_injection(unsigned char *font, unsigned char *textures, ItemInstance *item_instance, float param_1, float param_2, float param_3, float param_4, bool param_5) { static void ItemRenderer_renderGuiItem_two_injection(Font *font, Textures *textures, ItemInstance *item_instance, float param_1, float param_2, float param_3, float param_4, bool param_5) {
// Call Original Method // Call Original Method
(*ItemRenderer_renderGuiItem_two)(font, textures, item_instance, param_1, param_2, param_3, param_4, param_5); (*ItemRenderer_renderGuiItem_two)(font, textures, item_instance, param_1, param_2, param_3, param_4, param_5);
// Disable Item Color Fix // Disable Item Color Fix
item_color_fix_mode = 0; item_color_fix_mode = 0;
} }
static void FurnaceScreen_render_ItemRenderer_renderGuiItem_one_injection(unsigned char *font, unsigned char *textures, ItemInstance *item_instance, float param_1, float param_2, bool param_3) { static void FurnaceScreen_render_ItemRenderer_renderGuiItem_one_injection(Font *font, Textures *textures, ItemInstance *item_instance, float param_1, float param_2, bool param_3) {
// Enable Item Color Fix // Enable Item Color Fix
item_color_fix_mode = 1; item_color_fix_mode = 1;

View File

@ -36,7 +36,7 @@ __attribute__((constructor)) static void _init_active(int argc, char *argv[]) {
#define BENCHMARK_ROTATION_AMOUNT 10 #define BENCHMARK_ROTATION_AMOUNT 10
// Create/Start World // Create/Start World
static void start_world(unsigned char *minecraft) { static void start_world(Minecraft *minecraft) {
// Log // Log
INFO("Loading Benchmark"); INFO("Loading Benchmark");
@ -46,19 +46,18 @@ static void start_world(unsigned char *minecraft) {
settings.seed = BENCHMARK_SEED; settings.seed = BENCHMARK_SEED;
// Delete World If It Already Exists // Delete World If It Already Exists
unsigned char *level_source = (*Minecraft_getLevelSource)(minecraft); LevelStorageSource *level_source = (*Minecraft_getLevelSource)(minecraft);
unsigned char *level_source_vtable = *(unsigned char **) level_source; std::string name = BENCHMARK_WORLD_NAME;
ExternalFileLevelStorageSource_deleteLevel_t ExternalFileLevelStorageSource_deleteLevel = *(ExternalFileLevelStorageSource_deleteLevel_t *) (level_source_vtable + ExternalFileLevelStorageSource_deleteLevel_vtable_offset); level_source->vtable->deleteLevel(level_source, &name);
(*ExternalFileLevelStorageSource_deleteLevel)(level_source, BENCHMARK_WORLD_NAME);
// Select Level // Select Level
(*Minecraft_selectLevel)(minecraft, BENCHMARK_WORLD_NAME, BENCHMARK_WORLD_NAME, settings); minecraft->vtable->selectLevel(minecraft, &name, &name, &settings);
// Open ProgressScreen // Open ProgressScreen
void *screen = ::operator new(PROGRESS_SCREEN_SIZE); ProgressScreen *screen = alloc_ProgressScreen();
ALLOC_CHECK(screen); ALLOC_CHECK(screen);
screen = (*ProgressScreen)((unsigned char *) screen); screen = (*ProgressScreen_constructor)(screen);
(*Minecraft_setScreen)(minecraft, (unsigned char *) screen); (*Minecraft_setScreen)(minecraft, (Screen *) screen);
} }
// Track Frames // Track Frames
@ -73,7 +72,7 @@ HOOK(media_swap_buffers, void, ()) {
// Track Ticks // Track Ticks
static unsigned long long int ticks = 0; static unsigned long long int ticks = 0;
static void Minecraft_tick_injection(__attribute__((unused)) unsigned char *minecraft) { static void Minecraft_tick_injection(__attribute__((unused)) Minecraft *minecraft) {
ticks++; ticks++;
} }
@ -100,7 +99,7 @@ static int32_t last_logged_status = -1;
// Runs Every Tick // Runs Every Tick
static bool loaded = false; static bool loaded = false;
static bool exit_requested = false; static bool exit_requested = false;
static void Minecraft_update_injection(unsigned char *minecraft) { static void Minecraft_update_injection(Minecraft *minecraft) {
// Create/Start World // Create/Start World
if (!loaded) { if (!loaded) {
start_world(minecraft); start_world(minecraft);

View File

@ -6,22 +6,22 @@
#include <mods/misc/misc.h> #include <mods/misc/misc.h>
// Items // Items
unsigned char *bucket = NULL; Item *bucket = NULL;
// Description And Texture // Description And Texture
static std::string BucketItem_getDescriptionId(__attribute__((unused)) unsigned char *item, const ItemInstance *item_instance) { static std::string BucketItem_getDescriptionId(__attribute__((unused)) Item *item, ItemInstance *item_instance) {
if (item_instance->auxiliary == *(int32_t *) (*Tile_water + Tile_id_property_offset)) { if (item_instance->auxiliary == (*Tile_water)->id) {
return "item.bucketWater"; return "item.bucketWater";
} else if (item_instance->auxiliary == *(int32_t *) (*Tile_lava + Tile_id_property_offset)) { } else if (item_instance->auxiliary == (*Tile_lava)->id) {
return "item.bucketLava"; return "item.bucketLava";
} else { } else {
return "item.bucket"; return "item.bucket";
} }
} }
static int32_t BucketItem_getIcon(__attribute__((unused)) unsigned char *item, int32_t auxiliary) { static int32_t BucketItem_getIcon(__attribute__((unused)) Item *item, int32_t auxiliary) {
if (auxiliary == *(int32_t *) (*Tile_water + Tile_id_property_offset)) { if (auxiliary == (*Tile_water)->id) {
return 75; return 75;
} else if (auxiliary == *(int32_t *) (*Tile_lava + Tile_id_property_offset)) { } else if (auxiliary == (*Tile_lava)->id) {
return 76; return 76;
} else { } else {
return 74; return 74;
@ -29,17 +29,17 @@ static int32_t BucketItem_getIcon(__attribute__((unused)) unsigned char *item, i
} }
// Use Bucket // Use Bucket
static int32_t BucketItem_useOn(__attribute__((unused)) unsigned char *item, ItemInstance *item_instance, unsigned char *player, unsigned char *level, int32_t x, int32_t y, int32_t z, int32_t hit_side, __attribute__((unused)) float hit_x, __attribute__((unused)) float hit_y, __attribute__((unused)) float hit_z) { static int32_t BucketItem_useOn(__attribute__((unused)) Item *item, ItemInstance *item_instance, Player *player, Level *level, int32_t x, int32_t y, int32_t z, int32_t hit_side, __attribute__((unused)) float hit_x, __attribute__((unused)) float hit_y, __attribute__((unused)) float hit_z) {
if (item_instance->count < 1) { if (item_instance->count < 1) {
return 0; return 0;
} else if (item_instance->auxiliary == 0) { } else if (item_instance->auxiliary == 0) {
// Empty Bucket // Empty Bucket
int32_t new_auxiliary = 0; int32_t new_auxiliary = 0;
int32_t tile = (*Level_getTile)(level, x, y, z); int32_t tile = level->vtable->getTile(level, x, y, z);
if (tile == *(int32_t *) (*Tile_calmWater + Tile_id_property_offset)) { if (tile == (*Tile_calmWater)->id) {
new_auxiliary = *(int32_t *) (*Tile_water + Tile_id_property_offset); new_auxiliary = (*Tile_water)->id;
} else if (tile == *(int32_t *) (*Tile_calmLava + Tile_id_property_offset)) { } else if (tile == (*Tile_calmLava)->id) {
new_auxiliary = *(int32_t *) (*Tile_lava + Tile_id_property_offset); new_auxiliary = (*Tile_lava)->id;
} }
if (new_auxiliary != 0) { if (new_auxiliary != 0) {
// Valid // Valid
@ -49,13 +49,11 @@ static int32_t BucketItem_useOn(__attribute__((unused)) unsigned char *item, Ite
success = true; success = true;
} else { } else {
ItemInstance new_item; ItemInstance new_item;
new_item.id = *(int32_t *) (bucket + Item_id_property_offset); new_item.id = bucket->id;
new_item.count = 1; new_item.count = 1;
new_item.auxiliary = new_auxiliary; new_item.auxiliary = new_auxiliary;
unsigned char *inventory = *(unsigned char **) (player + Player_inventory_property_offset); Inventory *inventory = player->inventory;
unsigned char *inventory_vtable = *(unsigned char **) inventory; if (inventory->vtable->add(inventory, &new_item)) {
FillingContainer_add_t FillingContainer_add = *(FillingContainer_add_t *) (inventory_vtable + FillingContainer_add_vtable_offset);
if ((*FillingContainer_add)(inventory, &new_item)) {
// Added To Inventory // Added To Inventory
success = true; success = true;
item_instance->count -= 1; item_instance->count -= 1;
@ -101,13 +99,11 @@ static int32_t BucketItem_useOn(__attribute__((unused)) unsigned char *item, Ite
} }
// Get Current Tile // Get Current Tile
bool valid = false; bool valid = false;
unsigned char *material = (*Level_getMaterial)(level, x, y, z); Material *material = level->vtable->getMaterial(level, x, y, z);
if (material != NULL) { if (material != NULL) {
unsigned char *material_vtable = *(unsigned char **) material; valid = !material->vtable->isSolid(material);
Material_isSolid_t Material_isSolid = *(Material_isSolid_t *) (material_vtable + Material_isSolid_vtable_offset);
valid = !(*Material_isSolid)(material);
} }
if (item_instance->auxiliary != *(int32_t *) (*Tile_water + Tile_id_property_offset) && item_instance->auxiliary != *(int32_t *) (*Tile_lava + Tile_id_property_offset)) { if (item_instance->auxiliary != (*Tile_water)->id && item_instance->auxiliary != (*Tile_lava)->id) {
valid = false; valid = false;
} }
if (valid) { if (valid) {
@ -121,59 +117,49 @@ static int32_t BucketItem_useOn(__attribute__((unused)) unsigned char *item, Ite
} }
// Bucket VTable // Bucket VTable
static unsigned char *get_bucket_vtable() { static Item_vtable *get_bucket_vtable() {
static unsigned char *vtable = NULL; static Item_vtable *vtable = NULL;
if (vtable == NULL) { if (vtable == NULL) {
// Init // Init
vtable = (unsigned char *) malloc(ITEM_VTABLE_SIZE); vtable = dup_Item_vtable(Item_vtable_base);
ALLOC_CHECK(vtable); ALLOC_CHECK(vtable);
// Copy Old VTable
memcpy((void *) vtable, (void *) Item_vtable, ITEM_VTABLE_SIZE);
// Modify // Modify
*(Item_getDescriptionId_t *) (vtable + Item_getDescriptionId_vtable_offset) = BucketItem_getDescriptionId; vtable->getDescriptionId = BucketItem_getDescriptionId;
*(Item_getIcon_t *) (vtable + Item_getIcon_vtable_offset) = BucketItem_getIcon; vtable->getIcon = BucketItem_getIcon;
*(Item_useOn_t *) (vtable + Item_useOn_vtable_offset) = BucketItem_useOn; vtable->useOn = BucketItem_useOn;
} }
return vtable; return vtable;
} }
__attribute__((destructor)) static void free_bucket_vtable() {
free(get_bucket_vtable());
}
// Create Items // Create Items
static unsigned char *create_bucket(int32_t id, int32_t texture_x, int32_t texture_y, const char *name) { static Item *create_bucket(int32_t id, int32_t texture_x, int32_t texture_y, std::string name) {
// Construct // Construct
unsigned char *item = (unsigned char *) ::operator new(ITEM_SIZE); Item *item = alloc_Item();
ALLOC_CHECK(item); ALLOC_CHECK(item);
(*Item)(item, id); (*Item_constructor)(item, id);
// Set VTable // Set VTable
*(unsigned char **) item = get_bucket_vtable(); item->vtable = get_bucket_vtable();
// Get Functions
unsigned char *vtable = *(unsigned char **) item;
Item_setIcon_t Item_setIcon = *(Item_setIcon_t *) (vtable + Item_setIcon_vtable_offset);
Item_setDescriptionId_t Item_setDescriptionId = *(Item_setDescriptionId_t *) (vtable + Item_setDescriptionId_vtable_offset);
// Setup // Setup
(*Item_setIcon)(item, texture_x, texture_y); item->vtable->setIcon(item, texture_x, texture_y);
(*Item_setDescriptionId)(item, name); item->vtable->setDescriptionId(item, &name);
*(int32_t *) (item + Item_is_stacked_by_data_property_offset) = 1; item->is_stacked_by_data = 1;
*(int32_t *) (item + Item_category_property_offset) = 2; item->category = 2;
*(int32_t *) (item + Item_max_damage_property_offset) = 0; item->max_damage = 0;
*(int32_t *) (item + Item_max_stack_size_property_offset) = 1; item->max_stack_size = 1;
// Return // Return
return item; return item;
} }
static void Item_initItems_injection(__attribute__((unused)) unsigned char *null) { static void Item_initItems_injection(__attribute__((unused)) void *null) {
bucket = create_bucket(69, 10, 4, "bucket"); bucket = create_bucket(69, 10, 4, "bucket");
} }
// Change Max Stack Size Based On Auxiliary // Change Max Stack Size Based On Auxiliary
static int32_t ItemInstance_getMaxStackSize_injection(ItemInstance *item_instance) { static int32_t ItemInstance_getMaxStackSize_injection(ItemInstance *item_instance) {
if (item_instance->id == *(int32_t *) (bucket + Item_id_property_offset) && item_instance->auxiliary == 0) { if (item_instance->id == bucket->id && item_instance->auxiliary == 0) {
// Custom Value // Custom Value
return 16; return 16;
} else { } else {
@ -183,60 +169,56 @@ static int32_t ItemInstance_getMaxStackSize_injection(ItemInstance *item_instanc
} }
// Creative Inventory // Creative Inventory
static void inventory_add_item(unsigned char *inventory, unsigned char *item, int32_t auxiliary) { static void inventory_add_item(FillingContainer *inventory, Item *item, int32_t auxiliary) {
ItemInstance *item_instance = new ItemInstance; ItemInstance *item_instance = new ItemInstance;
ALLOC_CHECK(item_instance); ALLOC_CHECK(item_instance);
item_instance = (*ItemInstance_constructor_item_extra)(item_instance, item, 1, auxiliary); item_instance = (*ItemInstance_constructor_item_extra)(item_instance, item, 1, auxiliary);
(*FillingContainer_addItem)(inventory, item_instance); (*FillingContainer_addItem)(inventory, item_instance);
} }
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(unsigned char *filling_container) { static void Inventory_setupDefault_FillingContainer_addItem_call_injection(FillingContainer *filling_container) {
inventory_add_item(filling_container, bucket, 0); inventory_add_item(filling_container, bucket, 0);
inventory_add_item(filling_container, bucket, *(int32_t *) (*Tile_water + Tile_id_property_offset)); inventory_add_item(filling_container, bucket, (*Tile_water)->id);
inventory_add_item(filling_container, bucket, *(int32_t *) (*Tile_lava + Tile_id_property_offset)); inventory_add_item(filling_container, bucket, (*Tile_lava)->id);
} }
// Make Liquids Selectable // Make Liquids Selectable
static bool is_holding_bucket = false; static bool is_holding_bucket = false;
static HitResult Mob_pick_Level_clip_injection(unsigned char *level, unsigned char *param_1, unsigned char *param_2, __attribute__((unused)) bool clip_liquids, bool param_3) { static HitResult Mob_pick_Level_clip_injection(Level *level, unsigned char *param_1, unsigned char *param_2, __attribute__((unused)) bool clip_liquids, bool param_3) {
// Call Original Method // Call Original Method
return (*Level_clip)(level, param_1, param_2, is_holding_bucket, param_3); return (*Level_clip)(level, param_1, param_2, is_holding_bucket, param_3);
} }
static void handle_tick(unsigned char *minecraft) { static void handle_tick(Minecraft *minecraft) {
unsigned char *player = *(unsigned char **) (minecraft + Minecraft_player_property_offset); LocalPlayer *player = minecraft->player;
if (player != NULL) { if (player != NULL) {
// Get Selected Slot // Get Selected Slot
int32_t selected_slot = misc_get_real_selected_slot(player); int32_t selected_slot = misc_get_real_selected_slot((Player *) player);
unsigned char *inventory = *(unsigned char **) (player + Player_inventory_property_offset); Inventory *inventory = player->inventory;
// Prepare
unsigned char *inventory_vtable = *(unsigned char **) inventory;
FillingContainer_getItem_t FillingContainer_getItem = *(FillingContainer_getItem_t *) (inventory_vtable + FillingContainer_getItem_vtable_offset);
// Get Item // Get Item
ItemInstance *inventory_item = (*FillingContainer_getItem)(inventory, selected_slot); ItemInstance *inventory_item = inventory->vtable->getItem(inventory, selected_slot);
// Check // Check
is_holding_bucket = inventory_item != NULL && inventory_item->id == (*(int32_t *) (bucket + Item_id_property_offset)) && inventory_item->auxiliary == 0; is_holding_bucket = inventory_item != NULL && inventory_item->id == bucket->id && inventory_item->auxiliary == 0;
} }
} }
// Prevent Breaking Liquid // Prevent Breaking Liquid
static bool is_calm_liquid(int32_t id) { static bool is_calm_liquid(int32_t id) {
if (id == *(int32_t *) (*Tile_calmWater + Tile_id_property_offset)) { if (id == (*Tile_calmWater)->id) {
return true; return true;
} else if (id == *(int32_t *) (*Tile_calmLava + Tile_id_property_offset)) { } else if (id == (*Tile_calmLava)->id) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
static void Minecraft_handleMouseDown_injection(unsigned char *minecraft, int param_1, bool can_destroy) { static void Minecraft_handleMouseDown_injection(Minecraft *minecraft, int param_1, bool can_destroy) {
// Check // Check
unsigned char *level = *(unsigned char **) (minecraft + Minecraft_level_property_offset); Level *level = minecraft->level;
if (level != NULL) { if (level != NULL) {
int32_t x = *(int32_t *) (minecraft + Minecraft_targeted_x_property_offset); int32_t x = minecraft->hit_result.x;
int32_t y = *(int32_t *) (minecraft + Minecraft_targeted_y_property_offset); int32_t y = minecraft->hit_result.y;
int32_t z = *(int32_t *) (minecraft + Minecraft_targeted_z_property_offset); int32_t z = minecraft->hit_result.z;
int32_t tile = (*Level_getTile)(level, x, y, z); int32_t tile = level->vtable->getTile(level, x, y, z);
if (is_calm_liquid(tile)) { if (is_calm_liquid(tile)) {
can_destroy = false; can_destroy = false;
} }
@ -247,7 +229,7 @@ static void Minecraft_handleMouseDown_injection(unsigned char *minecraft, int pa
} }
// Custom Crafting Recipes // Custom Crafting Recipes
static void Recipes_injection(unsigned char *recipes) { static void Recipes_injection(Recipes *recipes) {
// Add // Add
Recipes_Type type1 = { Recipes_Type type1 = {
.item = 0, .item = 0,
@ -261,15 +243,18 @@ static void Recipes_injection(unsigned char *recipes) {
}; };
ItemInstance result = { ItemInstance result = {
.count = 1, .count = 1,
.id = (*(int32_t *) (bucket + Item_id_property_offset)), .id = bucket->id,
.auxiliary = 0 .auxiliary = 0
}; };
(*Recipes_addShapedRecipe_2)(recipes, result, "# #", " # ", {type1}); std::string line1 = "# #";
std::string line2 = " # ";
std::vector<Recipes_Type> types = {type1};
(*Recipes_addShapedRecipe_2)(recipes, &result, &line1, &line2, &types);
} }
// Custom Furnace Fuel // Custom Furnace Fuel
static int32_t FurnaceTileEntity_getBurnDuration_injection(ItemInstance const& item_instance) { static int32_t FurnaceTileEntity_getBurnDuration_injection(ItemInstance *item_instance) {
if (item_instance.count > 0 && item_instance.id == (*(int32_t *) (bucket + Item_id_property_offset)) && item_instance.auxiliary == (*(int32_t *) (*Tile_lava + Tile_id_property_offset))) { if (item_instance->count > 0 && item_instance->id == bucket->id && item_instance->auxiliary == (*Tile_lava)->id) {
return 20000; return 20000;
} else { } else {
// Call Original Method // Call Original Method
@ -278,7 +263,7 @@ static int32_t FurnaceTileEntity_getBurnDuration_injection(ItemInstance const& i
} }
static void FurnaceTileEntity_tick_ItemInstance_setNull_injection(ItemInstance *item_instance) { static void FurnaceTileEntity_tick_ItemInstance_setNull_injection(ItemInstance *item_instance) {
// Replace Lava Bucket With Empty Bucket When It Burns Out // Replace Lava Bucket With Empty Bucket When It Burns Out
if (item_instance->id == (*(int32_t *) (bucket + Item_id_property_offset))) { if (item_instance->id == bucket->id) {
item_instance->auxiliary = 0; item_instance->auxiliary = 0;
} else { } else {
// Original Behavior // Original Behavior

View File

@ -7,28 +7,28 @@
#include <mods/init/init.h> #include <mods/init/init.h>
// Take Screenshot Using TripodCamera // Take Screenshot Using TripodCamera
static void AppPlatform_linux_saveScreenshot_injection(__attribute__((unused)) unsigned char *app_platform, __attribute__((unused)) std::string const& path, __attribute__((unused)) int32_t width, __attribute__((unused)) int32_t height) { static void AppPlatform_linux_saveScreenshot_injection(__attribute__((unused)) AppPlatform *app_platform, __attribute__((unused)) std::string const& path, __attribute__((unused)) int32_t width, __attribute__((unused)) int32_t height) {
#ifndef MCPI_HEADLESS_MODE #ifndef MCPI_HEADLESS_MODE
screenshot_take(home_get()); screenshot_take(home_get());
#endif #endif
} }
// Enable TripodCameraRenderer // Enable TripodCameraRenderer
static unsigned char *EntityRenderDispatcher_injection(unsigned char *dispatcher) { static EntityRenderDispatcher *EntityRenderDispatcher_injection(EntityRenderDispatcher *dispatcher) {
// Call Original Method // Call Original Method
(*EntityRenderDispatcher)(dispatcher); (*EntityRenderDispatcher_constructor)(dispatcher);
// Register TripodCameraRenderer // Register TripodCameraRenderer
unsigned char *renderer = (unsigned char *) ::operator new(TRIPOD_CAMERA_RENDERER_SIZE); TripodCameraRenderer *renderer = alloc_TripodCameraRenderer();
ALLOC_CHECK(renderer); ALLOC_CHECK(renderer);
(*TripodCameraRenderer)(renderer); (*TripodCameraRenderer_constructor)(renderer);
(*EntityRenderDispatcher_assign)(dispatcher, (unsigned char) 0x5, renderer); (*EntityRenderDispatcher_assign)(dispatcher, (unsigned char) 0x5, (EntityRenderer *) renderer);
return dispatcher; return dispatcher;
} }
// Display Smoke From TripodCamera Higher // Display Smoke From TripodCamera Higher
static void TripodCamera_tick_Level_addParticle_call_injection(unsigned char *level, std::string const& particle, float x, float y, float z, float deltaX, float deltaY, float deltaZ, int count) { static void TripodCamera_tick_Level_addParticle_call_injection(Level *level, std::string *particle, float x, float y, float z, float deltaX, float deltaY, float deltaZ, int count) {
// Call Original Method // Call Original Method
(*Level_addParticle)(level, particle, x, y + 0.5, z, deltaX, deltaY, deltaZ, count); (*Level_addParticle)(level, particle, x, y + 0.5, z, deltaX, deltaY, deltaZ, count);
} }
@ -41,7 +41,7 @@ void init_camera() {
// Fix Camera Rendering // Fix Camera Rendering
if (feature_has("Fix Camera Rendering", server_disabled)) { if (feature_has("Fix Camera Rendering", server_disabled)) {
// Enable TripodCameraRenderer // Enable TripodCameraRenderer
overwrite_calls((void *) EntityRenderDispatcher, (void *) EntityRenderDispatcher_injection); overwrite_calls((void *) EntityRenderDispatcher_constructor, (void *) EntityRenderDispatcher_injection);
// Display Smoke From TripodCamera Higher // Display Smoke From TripodCamera Higher
overwrite_call((void *) 0x87dc4, (void *) TripodCamera_tick_Level_addParticle_call_injection); overwrite_call((void *) 0x87dc4, (void *) TripodCamera_tick_Level_addParticle_call_injection);
} }

View File

@ -29,14 +29,14 @@ int _chat_enabled = 0;
#define MAX_CHAT_MESSAGE_LENGTH 512 #define MAX_CHAT_MESSAGE_LENGTH 512
// Send API Command // Send API Command
std::string chat_send_api_command(unsigned char *minecraft, char *str) { std::string chat_send_api_command(Minecraft *minecraft, std::string str) {
struct ConnectedClient client; struct ConnectedClient client;
client.sock = -1; client.sock = -1;
client.str = ""; client.str = "";
client.time = 0; client.time = 0;
unsigned char *command_server = *(unsigned char **) (minecraft + Minecraft_command_server_property_offset); CommandServer *command_server = minecraft->command_server;
if (command_server != NULL) { if (command_server != NULL) {
return (*CommandServer_parse)(command_server, client, str); return (*CommandServer_parse)(command_server, &client, &str);
} else { } else {
return ""; return "";
} }
@ -44,7 +44,7 @@ std::string chat_send_api_command(unsigned char *minecraft, char *str) {
#ifndef MCPI_HEADLESS_MODE #ifndef MCPI_HEADLESS_MODE
// Send API Chat Command // Send API Chat Command
static void send_api_chat_command(unsigned char *minecraft, char *str) { static void send_api_chat_command(Minecraft *minecraft, char *str) {
char *command = NULL; char *command = NULL;
safe_asprintf(&command, "chat.post(%s)\n", str); safe_asprintf(&command, "chat.post(%s)\n", str);
chat_send_api_command(minecraft, command); chat_send_api_command(minecraft, command);
@ -53,45 +53,43 @@ static void send_api_chat_command(unsigned char *minecraft, char *str) {
#endif #endif
// Send Message To Players // Send Message To Players
void chat_send_message(unsigned char *server_side_network_handler, char *username, char *message) { void chat_send_message(ServerSideNetworkHandler *server_side_network_handler, char *username, char *message) {
char *full_message = NULL; char *full_message = NULL;
safe_asprintf(&full_message, "<%s> %s", username, message); safe_asprintf(&full_message, "<%s> %s", username, message);
sanitize_string(&full_message, MAX_CHAT_MESSAGE_LENGTH, 0); sanitize_string(&full_message, MAX_CHAT_MESSAGE_LENGTH, 0);
(*ServerSideNetworkHandler_displayGameMessage)(server_side_network_handler, std::string(full_message)); std::string cpp_string = full_message;
free(full_message); free(full_message);
(*ServerSideNetworkHandler_displayGameMessage)(server_side_network_handler, &cpp_string);
} }
// Handle Chat packet Send // Handle Chat packet Send
void chat_handle_packet_send(unsigned char *minecraft, unsigned char *packet) { void chat_handle_packet_send(Minecraft *minecraft, ChatPacket *packet) {
unsigned char *rak_net_instance = *(unsigned char **) (minecraft + Minecraft_rak_net_instance_property_offset); RakNetInstance *rak_net_instance = minecraft->rak_net_instance;
unsigned char *rak_net_instance_vtable = *(unsigned char **) rak_net_instance; if (rak_net_instance->vtable->isServer(rak_net_instance)) {
RakNetInstance_isServer_t RakNetInstance_isServer = *(RakNetInstance_isServer_t *) (rak_net_instance_vtable + RakNetInstance_isServer_vtable_offset);
if ((*RakNetInstance_isServer)(rak_net_instance)) {
// Hosting Multiplayer // Hosting Multiplayer
char *message = *(char **) (packet + ChatPacket_message_property_offset); char *message = packet->message;
unsigned char *server_side_network_handler = *(unsigned char **) (minecraft + Minecraft_network_handler_property_offset); ServerSideNetworkHandler *server_side_network_handler = (ServerSideNetworkHandler *) minecraft->network_handler;
chat_send_message(server_side_network_handler, *default_username, message); chat_send_message(server_side_network_handler, *Strings_default_username, message);
} else { } else {
// Client // Client
RakNetInstance_send_t RakNetInstance_send = *(RakNetInstance_send_t *) (rak_net_instance_vtable + RakNetInstance_send_vtable_offset); rak_net_instance->vtable->send(rak_net_instance, (Packet *) packet);
(*RakNetInstance_send)(rak_net_instance, packet);
} }
} }
// Manually Send (And Loopback) ChatPacket // Manually Send (And Loopback) ChatPacket
static void CommandServer_parse_CommandServer_dispatchPacket_injection(unsigned char *command_server, unsigned char *packet) { static void CommandServer_parse_CommandServer_dispatchPacket_injection(CommandServer *command_server, Packet *packet) {
unsigned char *minecraft = *(unsigned char **) (command_server + CommandServer_minecraft_property_offset); Minecraft *minecraft = command_server->minecraft;
if (minecraft != NULL) { if (minecraft != NULL) {
chat_handle_packet_send(minecraft, packet); chat_handle_packet_send(minecraft, (ChatPacket *) packet);
} }
} }
// Handle ChatPacket Server-Side // Handle ChatPacket Server-Side
static void ServerSideNetworkHandler_handle_ChatPacket_injection(unsigned char *server_side_network_handler, RakNet_RakNetGUID *rak_net_guid, unsigned char *chat_packet) { static void ServerSideNetworkHandler_handle_ChatPacket_injection(ServerSideNetworkHandler *server_side_network_handler, RakNet_RakNetGUID *rak_net_guid, ChatPacket *chat_packet) {
unsigned char *player = (*ServerSideNetworkHandler_getPlayer)(server_side_network_handler, rak_net_guid); Player *player = (*ServerSideNetworkHandler_getPlayer)(server_side_network_handler, rak_net_guid);
if (player != NULL) { if (player != NULL) {
char *username = *(char **) (player + Player_username_property_offset); const char *username = player->username.c_str();
char *message = *(char **) (chat_packet + ChatPacket_message_property_offset); char *message = chat_packet->message;
chat_send_message(server_side_network_handler, username, message); chat_send_message(server_side_network_handler, (char *) username, message);
} }
} }
@ -112,7 +110,7 @@ void _chat_queue_message(char *message) {
} }
// Empty Queue // Empty Queue
unsigned int old_chat_counter = 0; unsigned int old_chat_counter = 0;
static void send_queued_messages(unsigned char *minecraft) { static void send_queued_messages(Minecraft *minecraft) {
// Lock // Lock
pthread_mutex_lock(&queue_mutex); pthread_mutex_lock(&queue_mutex);
// If Message Was Submitted, No Other Chat Windows Are Open, And The Game Is Not Paused, Then Re-Lock Cursor // If Message Was Submitted, No Other Chat Windows Are Open, And The Game Is Not Paused, Then Re-Lock Cursor

View File

@ -8,20 +8,26 @@
#ifndef MCPI_SERVER_MODE #ifndef MCPI_SERVER_MODE
// Add Item To Inventory // Add Item To Inventory
static void inventory_add_item(unsigned char *inventory, unsigned char *item, bool is_tile) { static void inventory_add_item(FillingContainer *inventory, Item *item) {
ItemInstance *item_instance = new ItemInstance; ItemInstance *item_instance = new ItemInstance;
ALLOC_CHECK(item_instance); ALLOC_CHECK(item_instance);
item_instance = (*(is_tile ? ItemInstance_constructor_tile : ItemInstance_constructor_item))(item_instance, item); item_instance = (*ItemInstance_constructor_item)(item_instance, item);
(*FillingContainer_addItem)(inventory, item_instance);
}
static void inventory_add_item(FillingContainer *inventory, Tile *item) {
ItemInstance *item_instance = new ItemInstance;
ALLOC_CHECK(item_instance);
item_instance = (*ItemInstance_constructor_tile)(item_instance, item);
(*FillingContainer_addItem)(inventory, item_instance); (*FillingContainer_addItem)(inventory, item_instance);
} }
// Expand Creative Inventory // Expand Creative Inventory
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(unsigned char *filling_container) { static void Inventory_setupDefault_FillingContainer_addItem_call_injection(FillingContainer *filling_container) {
// Add Items // Add Items
inventory_add_item(filling_container, *Item_flintAndSteel, false); inventory_add_item(filling_container, *Item_flintAndSteel);
inventory_add_item(filling_container, *Item_snowball, false); inventory_add_item(filling_container, *Item_snowball);
inventory_add_item(filling_container, *Item_egg, false); inventory_add_item(filling_container, *Item_egg);
inventory_add_item(filling_container, *Item_shears, false); inventory_add_item(filling_container, *Item_shears);
// Dyes // Dyes
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
if (i == 15) { if (i == 15) {
@ -33,20 +39,20 @@ static void Inventory_setupDefault_FillingContainer_addItem_call_injection(unsig
new_item_instance = (*ItemInstance_constructor_item_extra)(new_item_instance, *Item_dye_powder, 1, i); new_item_instance = (*ItemInstance_constructor_item_extra)(new_item_instance, *Item_dye_powder, 1, i);
(*FillingContainer_addItem)(filling_container, new_item_instance); (*FillingContainer_addItem)(filling_container, new_item_instance);
} }
inventory_add_item(filling_container, *Item_camera, false); inventory_add_item(filling_container, *Item_camera);
// Add Tiles // Add Tiles
inventory_add_item(filling_container, *Tile_water, true); inventory_add_item(filling_container, *Tile_water);
inventory_add_item(filling_container, *Tile_lava, true); inventory_add_item(filling_container, *Tile_lava);
inventory_add_item(filling_container, *Tile_calmWater, true); inventory_add_item(filling_container, *Tile_calmWater);
inventory_add_item(filling_container, *Tile_calmLava, true); inventory_add_item(filling_container, *Tile_calmLava);
inventory_add_item(filling_container, *Tile_glowingObsidian, true); inventory_add_item(filling_container, *Tile_glowingObsidian);
inventory_add_item(filling_container, *Tile_web, true); inventory_add_item(filling_container, *Tile_web);
inventory_add_item(filling_container, *Tile_topSnow, true); inventory_add_item(filling_container, *Tile_topSnow);
inventory_add_item(filling_container, *Tile_ice, true); inventory_add_item(filling_container, *Tile_ice);
inventory_add_item(filling_container, *Tile_invisible_bedrock, true); inventory_add_item(filling_container, *Tile_invisible_bedrock);
inventory_add_item(filling_container, *Tile_bedrock, true); inventory_add_item(filling_container, *Tile_bedrock);
inventory_add_item(filling_container, *Tile_info_updateGame1, true); inventory_add_item(filling_container, *Tile_info_updateGame1);
inventory_add_item(filling_container, *Tile_info_updateGame2, true); inventory_add_item(filling_container, *Tile_info_updateGame2);
// Nether Reactor // Nether Reactor
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if (i == 0) { if (i == 0) {
@ -80,19 +86,19 @@ static void Inventory_setupDefault_FillingContainer_addItem_call_injection(unsig
#endif #endif
// Hook Specific TileItem Constructor // Hook Specific TileItem Constructor
static unsigned char *Tile_initTiles_TileItem_injection(unsigned char *tile_item, int32_t id) { static TileItem *Tile_initTiles_TileItem_injection(TileItem *tile_item, int32_t id) {
// Call Original Method // Call Original Method
unsigned char *ret = (*TileItem)(tile_item, id); (*TileItem_constructor)(tile_item, id);
// Switch VTable // Switch VTable
*(unsigned char **) tile_item = AuxDataTileItem_vtable; tile_item->vtable = (TileItem_vtable *) AuxDataTileItem_vtable_base;
// Configure Item // Configure Item
*(bool *) (tile_item + Item_is_stacked_by_data_property_offset) = true; tile_item->is_stacked_by_data = true;
*(int32_t *) (tile_item + Item_max_damage_property_offset) = 0; tile_item->max_damage = 0;
*(unsigned char **) (tile_item + AuxDataTileItem_icon_tile_property_offset) = Tile_tiles[id + 0x100]; ((AuxDataTileItem *) tile_item)->icon_tile = Tile_tiles[id + 0x100];
// Return // Return
return ret; return tile_item;
} }
// Check Restriction Status // Check Restriction Status

View File

@ -7,9 +7,9 @@
#include <mods/feature/feature.h> #include <mods/feature/feature.h>
// Death Messages // Death Messages
static std::string get_death_message(unsigned char *player) { static std::string get_death_message(Player *player) {
// Get Username // Get Username
std::string *username = (std::string *) (player + Player_username_property_offset); std::string *username = &player->username;
// Prepare Death Message // Prepare Death Message
std::string message; std::string message;
@ -20,44 +20,36 @@ static std::string get_death_message(unsigned char *player) {
return message; return message;
} }
// Common Death Message Logic // Death Message Logic
static void Player_actuallyHurt_injection_helper(unsigned char *player, int32_t damage, bool is_local_player) { #define Player_actuallyHurt_injection(type) \
// Store Old Health static void type##Player_actuallyHurt_injection(type##Player *player, int32_t damage) { \
int32_t old_health = *(int32_t *) (player + Mob_health_property_offset); /* Store Old Health */ \
int32_t old_health = player->health; \
// Call Original Method \
(*(is_local_player ? LocalPlayer_actuallyHurt : Mob_actuallyHurt))(player, damage); /* Call Original Method */ \
(*type##Player_actuallyHurt_non_virtual)(player, damage); \
// Store New Health \
int32_t new_health = *(int32_t *) (player + Mob_health_property_offset); /* Store New Health */ \
int32_t new_health = player->health; \
// Get Variables \
unsigned char *minecraft = *(unsigned char **) (player + (is_local_player ? LocalPlayer_minecraft_property_offset : ServerPlayer_minecraft_property_offset)); /* Get Variables */ \
unsigned char *rak_net_instance = *(unsigned char **) (minecraft + Minecraft_rak_net_instance_property_offset); Minecraft *minecraft = player->minecraft; \
unsigned char *rak_net_instance_vtable = *(unsigned char **) rak_net_instance; RakNetInstance *rak_net_instance = minecraft->rak_net_instance; \
// Only Run On Server-Side /* Only Run On Server-Side */ \
RakNetInstance_isServer_t RakNetInstance_isServer = *(RakNetInstance_isServer_t *) (rak_net_instance_vtable + RakNetInstance_isServer_vtable_offset); if (rak_net_instance->vtable->isServer(rak_net_instance)) { \
if ((*RakNetInstance_isServer)(rak_net_instance)) { /* Check Health */ \
// Check Health if (new_health < 1 && old_health >= 1) { \
if (new_health < 1 && old_health >= 1) { /* Get Death Message */ \
// Get Death Message std::string message = get_death_message((Player *) player); \
std::string message = get_death_message(player); \
/* Post Death Message */ \
// Post Death Message ServerSideNetworkHandler *server_side_network_handler = (ServerSideNetworkHandler *) minecraft->network_handler; \
unsigned char *server_side_network_handler = *(unsigned char **) (minecraft + Minecraft_network_handler_property_offset); (*ServerSideNetworkHandler_displayGameMessage)(server_side_network_handler, &message); \
(*ServerSideNetworkHandler_displayGameMessage)(server_side_network_handler, message); } \
} } \
} }
} Player_actuallyHurt_injection(Local)
Player_actuallyHurt_injection(Server)
// ServerPlayer Death Message Logic
static void ServerPlayer_actuallyHurt_injection(unsigned char *player, int32_t damage) {
Player_actuallyHurt_injection_helper(player, damage, false);
}
// LocalPlayer Death Message Logic
static void LocalPlayer_actuallyHurt_injection(unsigned char *player, int32_t damage) {
Player_actuallyHurt_injection_helper(player, damage, true);
}
// Init // Init
void init_death() { void init_death() {

View File

@ -21,14 +21,14 @@ static void set_is_survival(int new_is_survival) {
patch((void *) 0x16ee4, size_patch); patch((void *) 0x16ee4, size_patch);
// Replace Default CreatorMode Constructor With CreatorMode Or SurvivalMode Constructor // Replace Default CreatorMode Constructor With CreatorMode Or SurvivalMode Constructor
overwrite_call((void *) 0x16ef4, new_is_survival ? SurvivalMode : CreatorMode); overwrite_call((void *) 0x16ef4, new_is_survival ? (void *) SurvivalMode_constructor : (void *) CreatorMode_constructor);
is_survival = new_is_survival; is_survival = new_is_survival;
} }
} }
// Handle Gamemode Switching // Handle Gamemode Switching
static void Minecraft_setIsCreativeMode_injection(unsigned char *this, int32_t new_game_mode) { static void Minecraft_setIsCreativeMode_injection(Minecraft *this, int32_t new_game_mode) {
set_is_survival(!new_game_mode); set_is_survival(!new_game_mode);
// Call Original Method // Call Original Method
@ -36,7 +36,7 @@ static void Minecraft_setIsCreativeMode_injection(unsigned char *this, int32_t n
} }
// Disable CreatorMode-Specific API Features (Polling Block Hits) In SurvivalMode, This Is Preferable To Crashing // Disable CreatorMode-Specific API Features (Polling Block Hits) In SurvivalMode, This Is Preferable To Crashing
static unsigned char *Minecraft_getCreator_injection(unsigned char *minecraft) { static unsigned char *Minecraft_getCreator_injection(Minecraft *minecraft) {
if (is_survival) { if (is_survival) {
// SurvivalMode, Return NULL // SurvivalMode, Return NULL
return NULL; return NULL;
@ -54,7 +54,7 @@ void init_game_mode() {
overwrite_calls((void *) Minecraft_setIsCreativeMode, (void *) Minecraft_setIsCreativeMode_injection); overwrite_calls((void *) Minecraft_setIsCreativeMode, (void *) Minecraft_setIsCreativeMode_injection);
// Replace CreatorLevel With ServerLevel (This Fixes Beds And Mob Spawning) // Replace CreatorLevel With ServerLevel (This Fixes Beds And Mob Spawning)
overwrite_call((void *) 0x16f84, (void *) ServerLevel); overwrite_call((void *) 0x16f84, (void *) ServerLevel_constructor);
// Allocate Correct Size For ServerLevel // Allocate Correct Size For ServerLevel
uint32_t level_size = SERVER_LEVEL_SIZE; uint32_t level_size = SERVER_LEVEL_SIZE;

View File

@ -51,12 +51,12 @@ typedef enum {
DIALOG_OPEN, DIALOG_OPEN,
DIALOG_SUCCESS DIALOG_SUCCESS
} create_world_state_dialog_t; } create_world_state_dialog_t;
typedef struct { struct create_world_state_t {
volatile create_world_state_dialog_t dialog_state = DIALOG_CLOSED; volatile create_world_state_dialog_t dialog_state = DIALOG_CLOSED;
volatile char *name = NULL; volatile char *name = NULL;
volatile int32_t game_mode = 0; volatile int32_t game_mode = 0;
volatile int32_t seed = 0; volatile int32_t seed = 0;
} create_world_state_t; };
static create_world_state_t create_world_state; static create_world_state_t create_world_state;
// Destructor // Destructor
__attribute__((destructor)) static void _free_create_world_state_name() { __attribute__((destructor)) static void _free_create_world_state_name() {
@ -80,9 +80,9 @@ static void reset_create_world_state() {
#define GAME_MODE_DIALOG_SIZE "200" #define GAME_MODE_DIALOG_SIZE "200"
static void *create_world_thread(__attribute__((unused)) void *nop) { static void *create_world_thread(__attribute__((unused)) void *nop) {
// Run Dialogs // Run Dialogs
char *world_name = NULL;
{ {
// World Name // World Name
char *world_name = NULL;
{ {
// Open // Open
const char *command[] = { const char *command[] = {
@ -201,6 +201,7 @@ static void *create_world_thread(__attribute__((unused)) void *nop) {
pthread_mutex_lock(&create_world_state_lock); pthread_mutex_lock(&create_world_state_lock);
reset_create_world_state(); reset_create_world_state();
pthread_mutex_unlock(&create_world_state_lock); pthread_mutex_unlock(&create_world_state_lock);
free(world_name);
// Return // Return
return NULL; return NULL;
} }
@ -214,15 +215,10 @@ static void open_create_world() {
pthread_create(&thread, NULL, create_world_thread, NULL); pthread_create(&thread, NULL, create_world_thread, NULL);
} }
// Get Minecraft From Screen
static unsigned char *get_minecraft_from_screen(unsigned char *screen) {
return *(unsigned char **) (screen + Screen_minecraft_property_offset);
}
// Create World // Create World
static void create_world(unsigned char *host_screen, std::string folder_name) { static void create_world(Screen *host_screen, std::string folder_name) {
// Get Minecraft // Get Minecraft
unsigned char *minecraft = get_minecraft_from_screen(host_screen); Minecraft *minecraft = host_screen->minecraft;
// Settings // Settings
LevelSettings settings; LevelSettings settings;
@ -231,16 +227,16 @@ static void create_world(unsigned char *host_screen, std::string folder_name) {
// Create World // Create World
std::string world_name = (char *) create_world_state.name; std::string world_name = (char *) create_world_state.name;
(*Minecraft_selectLevel)(minecraft, folder_name, world_name, settings); minecraft->vtable->selectLevel(minecraft, &folder_name, &world_name, &settings);
// Multiplayer // Multiplayer
(*Minecraft_hostMultiplayer)(minecraft, 19132); (*Minecraft_hostMultiplayer)(minecraft, 19132);
// Open ProgressScreen // Open ProgressScreen
unsigned char *screen = (unsigned char *) ::operator new(PROGRESS_SCREEN_SIZE); ProgressScreen *screen = alloc_ProgressScreen();
ALLOC_CHECK(screen); ALLOC_CHECK(screen);
screen = (*ProgressScreen)(screen); screen = (*ProgressScreen_constructor)(screen);
(*Minecraft_setScreen)(minecraft, screen); (*Minecraft_setScreen)(minecraft, (Screen *) screen);
// Reset // Reset
reset_create_world_state(); reset_create_world_state();
@ -248,11 +244,11 @@ static void create_world(unsigned char *host_screen, std::string folder_name) {
// Redirect Create World Button // Redirect Create World Button
#define create_SelectWorldScreen_tick_injection(prefix) \ #define create_SelectWorldScreen_tick_injection(prefix) \
static void prefix##SelectWorldScreen_tick_injection(unsigned char *screen) { \ static void prefix##SelectWorldScreen_tick_injection(prefix##SelectWorldScreen *screen) { \
/* Lock */ \ /* Lock */ \
pthread_mutex_lock(&create_world_state_lock); \ pthread_mutex_lock(&create_world_state_lock); \
\ \
bool *should_create_world = (bool *) (screen + prefix##SelectWorldScreen_should_create_world_property_offset); \ bool *should_create_world = &screen->should_create_world; \
if (*should_create_world) { \ if (*should_create_world) { \
/* Check State */ \ /* Check State */ \
if (create_world_state.dialog_state == DIALOG_CLOSED) { \ if (create_world_state.dialog_state == DIALOG_CLOSED) { \
@ -264,7 +260,7 @@ static void create_world(unsigned char *host_screen, std::string folder_name) {
*should_create_world = false; \ *should_create_world = false; \
} else { \ } else { \
/* Call Original Method */ \ /* Call Original Method */ \
(*prefix##SelectWorldScreen_tick)(screen); \ (*prefix##SelectWorldScreen_tick_non_virtual)(screen); \
} \ } \
\ \
/* Create World If Dialog Succeeded */ \ /* Create World If Dialog Succeeded */ \
@ -273,10 +269,10 @@ static void create_world(unsigned char *host_screen, std::string folder_name) {
\ \
/* Get New World Name */ \ /* Get New World Name */ \
std::string name = (char *) create_world_state.name; \ std::string name = (char *) create_world_state.name; \
std::string new_name = (*prefix##SelectWorldScreen_getUniqueLevelName)(screen, name); \ std::string new_name = (*prefix##SelectWorldScreen_getUniqueLevelName)(screen, &name); \
\ \
/* Create World */ \ /* Create World */ \
create_world(screen, new_name); \ create_world((Screen *) screen, new_name); \
} \ } \
\ \
/* Lock/Unlock UI */ \ /* Lock/Unlock UI */ \

View File

@ -24,7 +24,7 @@ __attribute__((destructor)) static void _free_home() {
// Init // Init
void init_home() { void init_home() {
// Store Data In ~/.minecraft-pi Instead Of ~/.minecraft // Store Data In ~/.minecraft-pi Instead Of ~/.minecraft
patch_address((void *) default_path, (void *) HOME_SUBDIRECTORY_FOR_GAME_DATA); patch_address((void *) Strings_default_path, (void *) HOME_SUBDIRECTORY_FOR_GAME_DATA);
// The override code resolves assets manually, // The override code resolves assets manually,
// making changing directory redundant. // making changing directory redundant.

View File

@ -1,12 +1,12 @@
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#include <mods/init/init.h> #include <mods/init/init.h>
#include <media-layer/core.h> #include <media-layer/core.h>
#include <symbols/minecraft.h>
__attribute__((constructor)) static void init() { __attribute__((constructor)) static void init() {
media_ensure_loaded(); media_ensure_loaded();
run_tests(); run_tests();
init_symbols();
init_version(); init_version();
init_compat(); init_compat();
#ifdef MCPI_SERVER_MODE #ifdef MCPI_SERVER_MODE

View File

@ -14,15 +14,15 @@ void input_set_is_left_click(int val) {
} }
// Add Attacking To MouseBuildInput // Add Attacking To MouseBuildInput
static int32_t MouseBuildInput_tickBuild_injection(unsigned char *mouse_build_input, unsigned char *local_player, uint32_t *build_action_intention_return) { static int32_t MouseBuildInput_tickBuild_injection(MouseBuildInput *mouse_build_input, Player *local_player, uint32_t *build_action_intention_return) {
// Call Original Method // Call Original Method
int32_t ret = (*MouseBuildInput_tickBuild)(mouse_build_input, local_player, build_action_intention_return); int32_t ret = (*MouseBuildInput_tickBuild_non_virtual)(mouse_build_input, local_player, build_action_intention_return);
// Use Attack/Place BuildActionIntention If No Other Valid BuildActionIntention Was Selected And This Was Not A Repeated Left Click // Use Attack/Place BuildActionIntention If No Other Valid BuildActionIntention Was Selected And This Was Not A Repeated Left Click
if (ret != 0 && is_left_click == 1 && *build_action_intention_return == 0xa) { if (ret != 0 && is_left_click == 1 && *build_action_intention_return == 0xa) {
// Get Target HitResult // Get Target HitResult
unsigned char *minecraft = *(unsigned char **) (local_player + LocalPlayer_minecraft_property_offset); Minecraft *minecraft = ((LocalPlayer *) local_player)->minecraft;
HitResult *hit_result = (HitResult *) (minecraft + Minecraft_hit_result_property_offset); HitResult *hit_result = &minecraft->hit_result;
int32_t hit_result_type = hit_result->type; int32_t hit_result_type = hit_result->type;
// Check if The Target Is An Entity Using HitResult // Check if The Target Is An Entity Using HitResult
if (hit_result_type == 1) { if (hit_result_type == 1) {
@ -37,14 +37,12 @@ static int32_t MouseBuildInput_tickBuild_injection(unsigned char *mouse_build_in
// Fix Holding Attack // Fix Holding Attack
static bool last_player_attack_successful = 0; static bool last_player_attack_successful = 0;
static bool Player_attack_Entity_hurt_injection(unsigned char *entity, unsigned char *attacker, int32_t damage) { static bool Player_attack_Entity_hurt_injection(Entity *entity, Entity *attacker, int32_t damage) {
// Call Original Method // Call Original Method
unsigned char *entity_vtable = *(unsigned char **) entity; last_player_attack_successful = entity->vtable->hurt(entity, attacker, damage);
Entity_hurt_t Entity_hurt = *(Entity_hurt_t *) (entity_vtable + Entity_hurt_vtable_offset);
last_player_attack_successful = (*Entity_hurt)(entity, attacker, damage);
return last_player_attack_successful; return last_player_attack_successful;
} }
static ItemInstance *Player_attack_Inventory_getSelected_injection(unsigned char *inventory) { static ItemInstance *Player_attack_Inventory_getSelected_injection(Inventory *inventory) {
// Check If Attack Was Successful // Check If Attack Was Successful
if (!last_player_attack_successful) { if (!last_player_attack_successful) {
return NULL; return NULL;

View File

@ -15,16 +15,12 @@ void input_set_is_right_click(int val) {
static int fix_bow = 0; static int fix_bow = 0;
// Handle Bow & Arrow // Handle Bow & Arrow
static void _handle_bow(unsigned char *minecraft) { static void _handle_bow(Minecraft *minecraft) {
if (fix_bow && !is_right_click) { if (fix_bow && !is_right_click) {
// GameMode Is Offset From minecraft By 0x160 GameMode *game_mode = minecraft->game_mode;
// Player Is Offset From minecraft By 0x18c LocalPlayer *player = minecraft->player;
unsigned char *game_mode = *(unsigned char **) (minecraft + Minecraft_game_mode_property_offset); if (player != NULL && game_mode != NULL && (*LocalPlayer_isUsingItem)(player)) {
unsigned char *player = *(unsigned char **) (minecraft + Minecraft_player_property_offset); game_mode->vtable->releaseUsingItem(game_mode, (Player *) player);
if (player != NULL && game_mode != NULL && (*Player_isUsingItem)(player)) {
unsigned char *game_mode_vtable = *(unsigned char **) game_mode;
GameMode_releaseUsingItem_t GameMode_releaseUsingItem = *(GameMode_releaseUsingItem_t *) (game_mode_vtable + GameMode_releaseUsingItem_vtable_offset);
(*GameMode_releaseUsingItem)(game_mode, player);
} }
} }
} }

View File

@ -10,16 +10,16 @@ static int should_open_crafting = 0;
void input_open_crafting() { void input_open_crafting() {
should_open_crafting = 1; should_open_crafting = 1;
} }
static void _handle_open_crafting(unsigned char *minecraft) { static void _handle_open_crafting(Minecraft *minecraft) {
if (should_open_crafting) { if (should_open_crafting) {
should_open_crafting = 0; should_open_crafting = 0;
// Set Screen // Set Screen
if (!creative_is_restricted() || !(*Minecraft_isCreativeMode)(minecraft)) { if (!creative_is_restricted() || !(*Minecraft_isCreativeMode)(minecraft)) {
unsigned char *screen = (unsigned char *) ::operator new(WORKBENCH_SCREEN_SIZE); WorkbenchScreen *screen = alloc_WorkbenchScreen();
ALLOC_CHECK(screen); ALLOC_CHECK(screen);
screen = (*WorkbenchScreen)(screen, 0); screen = (*WorkbenchScreen_constructor)(screen, 0);
(*Minecraft_setScreen)(minecraft, screen); (*Minecraft_setScreen)(minecraft, (Screen *) screen);
} }
} }
} }

View File

@ -24,23 +24,17 @@ void input_drop(int drop_slot) {
} }
// Handle Drop Item Presses // Handle Drop Item Presses
static void _handle_drop(unsigned char *minecraft) { static void _handle_drop(Minecraft *minecraft) {
if (((*(unsigned char **) (minecraft + Minecraft_screen_property_offset)) == NULL) && (!creative_is_restricted() || !(*Minecraft_isCreativeMode)(minecraft)) && (drop_item_presses > 0 || drop_slot_pressed)) { if ((minecraft->screen == NULL) && (!creative_is_restricted() || !(*Minecraft_isCreativeMode)(minecraft)) && (drop_item_presses > 0 || drop_slot_pressed)) {
// Get Player // Get Player
unsigned char *player = *(unsigned char **) (minecraft + Minecraft_player_property_offset); LocalPlayer *player = minecraft->player;
if (player != NULL) { if (player != NULL) {
// Get Selected Slot // Get Selected Slot
int32_t selected_slot = misc_get_real_selected_slot(player); int32_t selected_slot = misc_get_real_selected_slot((Player *) player);
unsigned char *inventory = *(unsigned char **) (player + Player_inventory_property_offset); Inventory *inventory = player->inventory;
// Prepare
unsigned char *player_vtable = *(unsigned char **) player;
Player_drop_t Player_drop = *(Player_drop_t *) (player_vtable + Player_drop_vtable_offset);
unsigned char *inventory_vtable = *(unsigned char **) inventory;
FillingContainer_getItem_t FillingContainer_getItem = *(FillingContainer_getItem_t *) (inventory_vtable + FillingContainer_getItem_vtable_offset);
// Get Item // Get Item
ItemInstance *inventory_item = (*FillingContainer_getItem)(inventory, selected_slot); ItemInstance *inventory_item = inventory->vtable->getItem(inventory, selected_slot);
// Check // Check
if (inventory_item != NULL && inventory_item->count > 0) { if (inventory_item != NULL && inventory_item->count > 0) {
// Copy // Copy
@ -65,12 +59,12 @@ static void _handle_drop(unsigned char *minecraft) {
// Empty Slot If Needed // Empty Slot If Needed
if (inventory_item->count < 1) { if (inventory_item->count < 1) {
(*FillingContainer_release)(inventory, selected_slot); (*Inventory_release)(inventory, selected_slot);
(*FillingContainer_compressLinkedSlotList)(inventory, selected_slot); (*Inventory_compressLinkedSlotList)(inventory, selected_slot);
} }
// Drop // Drop
(*Player_drop)(player, dropped_item, false); player->vtable->drop(player, dropped_item, false);
} }
} }
} }

View File

@ -19,7 +19,7 @@ void input_run_on_tick(input_tick_function_t function) {
} }
// Handle Input Fixes // Handle Input Fixes
static void Minecraft_tickInput_injection(unsigned char *minecraft) { static void Minecraft_tickInput_injection(Minecraft *minecraft) {
// Call Original Method // Call Original Method
(*Minecraft_tickInput)(minecraft); (*Minecraft_tickInput)(minecraft);

View File

@ -21,42 +21,38 @@ int input_back() {
} }
// Handle Back Button Presses // Handle Back Button Presses
static void _handle_back(unsigned char *minecraft) { static void _handle_back(Minecraft *minecraft) {
// If Minecraft's Level property is initialized, but Minecraft's Player property is NULL, then Minecraft::handleBack may crash. // If Minecraft's Level property is initialized, but Minecraft's Player property is NULL, then Minecraft::handleBack may crash.
if ((*(unsigned char **) (minecraft + Minecraft_level_property_offset)) != NULL && (*(unsigned char **) (minecraft + Minecraft_player_property_offset)) == NULL) { if (minecraft->level != NULL && minecraft->player == NULL) {
// Unable to safely run Minecraft::handleBack, deferring until safe. // Unable to safely run Minecraft::handleBack, deferring until safe.
return; return;
} }
// Send Event // Send Event
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++) { for (int i = 0; i < back_button_presses; i++) {
(*Minecraft_handleBack)(minecraft, 0); minecraft->vtable->handleBack(minecraft, 0);
} }
back_button_presses = 0; back_button_presses = 0;
} }
// Fix OptionsScreen Ignoring The Back Button // Fix OptionsScreen Ignoring The Back Button
static int32_t OptionsScreen_handleBackEvent_injection(unsigned char *screen, bool do_nothing) { static int32_t OptionsScreen_handleBackEvent_injection(OptionsScreen *screen, bool do_nothing) {
if (!do_nothing) { if (!do_nothing) {
unsigned char *minecraft = *(unsigned char **) (screen + Screen_minecraft_property_offset); Minecraft *minecraft = screen->minecraft;
(*Minecraft_setScreen)(minecraft, NULL); (*Minecraft_setScreen)(minecraft, NULL);
} }
return 1; return 1;
} }
// Fix "Sleeping Beauty" Bug // Fix "Sleeping Beauty" Bug
static int32_t InBedScreen_handleBackEvent_injection(unsigned char *screen, bool do_nothing) { static int32_t InBedScreen_handleBackEvent_injection(InBedScreen *screen, bool do_nothing) {
if (!do_nothing) { if (!do_nothing) {
// Close Screen // Close Screen
unsigned char *minecraft = *(unsigned char **) (screen + Screen_minecraft_property_offset); Minecraft *minecraft = screen->minecraft;
(*Minecraft_setScreen)(minecraft, NULL); (*Minecraft_setScreen)(minecraft, NULL);
// Stop Sleeping // Stop Sleeping
unsigned char *player = *(unsigned char **) (minecraft + Minecraft_player_property_offset); LocalPlayer *player = minecraft->player;
if (player != NULL) { if (player != NULL) {
unsigned char *player_vtable = *(unsigned char **) player; player->vtable->stopSleepInBed(player, 1, 1, 1);
Player_stopSleepInBed_t Player_stopSleepInBed = *(Player_stopSleepInBed_t *) (player_vtable + Player_stopSleepInBed_vtable_offset);
(*Player_stopSleepInBed)(player, 1, 1, 1);
} }
} }
return 1; return 1;
@ -69,7 +65,7 @@ void input_set_mouse_grab_state(int state) {
} }
// Grab/Un-Grab Mouse // Grab/Un-Grab Mouse
static void _handle_mouse_grab(unsigned char *minecraft) { static void _handle_mouse_grab(Minecraft *minecraft) {
if (mouse_grab_state == -1) { if (mouse_grab_state == -1) {
// Grab // Grab
(*Minecraft_grabMouse)(minecraft); (*Minecraft_grabMouse)(minecraft);
@ -83,7 +79,7 @@ static void _handle_mouse_grab(unsigned char *minecraft) {
#include <SDL/SDL.h> #include <SDL/SDL.h>
// Block UI Interaction When Mouse Is Locked // Block UI Interaction When Mouse Is Locked
static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(unsigned char *minecraft) { static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(Minecraft *minecraft) {
if (!enable_misc || SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) { if (!enable_misc || SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
// Call Original Method // Call Original Method
return creative_is_restricted() && (*Minecraft_isCreativeMode)(minecraft); return creative_is_restricted() && (*Minecraft_isCreativeMode)(minecraft);
@ -94,7 +90,7 @@ static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(unsigned ch
} }
// Block UI Interaction When Mouse Is Locked // Block UI Interaction When Mouse Is Locked
static void Gui_handleClick_injection(unsigned char *gui, int32_t param_2, int32_t param_3, int32_t param_4) { static void Gui_handleClick_injection(Gui *gui, int32_t param_2, int32_t param_3, int32_t param_4) {
if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) { if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) {
// Call Original Method // Call Original Method
(*Gui_handleClick)(gui, param_2, param_3, param_4); (*Gui_handleClick)(gui, param_2, param_3, param_4);

View File

@ -19,59 +19,59 @@ void input_third_person() {
} }
// Handle Toggle Options // Handle Toggle Options
static void _handle_toggle_options(unsigned char *minecraft) { static void _handle_toggle_options(Minecraft *minecraft) {
if (enable_toggles) { if (enable_toggles) {
// Handle Functions // Handle Functions
unsigned char *options = minecraft + Minecraft_options_property_offset; Options *options = &minecraft->options;
if (hide_gui_toggle % 2 != 0) { if (hide_gui_toggle % 2 != 0) {
// Toggle Hide GUI // Toggle Hide GUI
*(options + Options_hide_gui_property_offset) = *(options + Options_hide_gui_property_offset) ^ 1; options->hide_gui = options->hide_gui ^ 1;
} }
hide_gui_toggle = 0; hide_gui_toggle = 0;
if (third_person_toggle % 2 != 0) { if (third_person_toggle % 2 != 0) {
// Toggle Third Person // Toggle Third Person
*(options + Options_third_person_property_offset) = (*(options + Options_third_person_property_offset) + 1) % 3; options->third_person = (options->third_person + 1) % 3;
} }
third_person_toggle = 0; third_person_toggle = 0;
// Fix Broken Value From Third-Person OptionsButton Toggle // Fix Broken Value From Third-Person OptionsButton Toggle
// (Because Front-Facing Code Repurposes A Boolean As A Ternary) // (Because Front-Facing Code Repurposes A Boolean As A Ternary)
if (*(options + Options_third_person_property_offset) == 3) { if (options->third_person == 3) {
*(options + Options_third_person_property_offset) = 0; options->third_person = 0;
} }
} }
} }
// Font-Facing View // Font-Facing View
static void invert_rotation(unsigned char *entity) { static void invert_rotation(Entity *entity) {
if (entity != NULL) { if (entity != NULL) {
*(float *) (entity + Entity_yaw_property_offset) = 180.f + (*(float *) (entity + Entity_yaw_property_offset)); entity->yaw = 180.f + entity->yaw;
*(float *) (entity + Entity_old_yaw_property_offset) = 180.f + (*(float *) (entity + Entity_old_yaw_property_offset)); entity->old_yaw = 180.f + entity->old_yaw;
*(float *) (entity + Entity_pitch_property_offset) = -(*(float *) (entity + Entity_pitch_property_offset)); entity->pitch = -entity->pitch;
*(float *) (entity + Entity_old_pitch_property_offset) = -(*(float *) (entity + Entity_old_pitch_property_offset)); entity->old_pitch = -entity->old_pitch;
} }
} }
static void revert_rotation(unsigned char *entity) { static void revert_rotation(Entity *entity) {
if (entity != NULL) { if (entity != NULL) {
*(float *) (entity + Entity_yaw_property_offset) = -180.f + (*(float *) (entity + Entity_yaw_property_offset)); entity->yaw = -180.f + entity->yaw;
*(float *) (entity + Entity_old_yaw_property_offset) = -180.f + (*(float *) (entity + Entity_old_yaw_property_offset)); entity->old_yaw = -180.f + entity->old_yaw;
*(float *) (entity + Entity_pitch_property_offset) = -(*(float *) (entity + Entity_pitch_property_offset)); entity->pitch = -entity->pitch;
*(float *) (entity + Entity_old_pitch_property_offset) = -(*(float *) (entity + Entity_old_pitch_property_offset)); entity->old_pitch = -entity->old_pitch;
} }
} }
static int is_front_facing = 0; static int is_front_facing = 0;
static unsigned char *stored_player = NULL; static LocalPlayer *stored_player = NULL;
static void GameRenderer_setupCamera_injection(unsigned char *game_renderer, float param_1, int param_2) { static void GameRenderer_setupCamera_injection(GameRenderer *game_renderer, float param_1, int param_2) {
// Get Objects // Get Objects
unsigned char *minecraft = *(unsigned char **) (game_renderer + GameRenderer_minecraft_property_offset); Minecraft *minecraft = game_renderer->minecraft;
stored_player = *(unsigned char **) (minecraft + Minecraft_player_property_offset); stored_player = minecraft->player;
// Check If In Third-Person // Check If In Third-Person
unsigned char *options = minecraft + Minecraft_options_property_offset; Options *options = &minecraft->options;
is_front_facing = (*(options + Options_third_person_property_offset) == 2); is_front_facing = (options->third_person == 2);
// Invert Rotation // Invert Rotation
if (is_front_facing) { if (is_front_facing) {
invert_rotation(stored_player); invert_rotation((Entity *) stored_player);
} }
// Call Original Method // Call Original Method
@ -79,21 +79,21 @@ static void GameRenderer_setupCamera_injection(unsigned char *game_renderer, flo
// Revert // Revert
if (is_front_facing) { if (is_front_facing) {
revert_rotation(stored_player); revert_rotation((Entity *) stored_player);
} }
} }
static void ParticleEngine_render_injection(unsigned char *particle_engine, unsigned char *entity, float param_2) { static void ParticleEngine_render_injection(ParticleEngine *particle_engine, Entity *entity, float param_2) {
// Invert Rotation // Invert Rotation
if (is_front_facing && stored_player == entity) { if (is_front_facing && (Entity *) stored_player == entity) {
invert_rotation(stored_player); invert_rotation((Entity *) stored_player);
} }
// Call Original Method // Call Original Method
(*ParticleEngine_render)(particle_engine, entity, param_2); (*ParticleEngine_render)(particle_engine, entity, param_2);
// Revert // Revert
if (is_front_facing && stored_player == entity) { if (is_front_facing && (Entity *) stored_player == entity) {
revert_rotation(stored_player); revert_rotation((Entity *) stored_player);
} }
} }

View File

@ -7,35 +7,35 @@
#include "misc-internal.h" #include "misc-internal.h"
// Callbacks // Callbacks
#define SETUP_CALLBACK(name) \ #define SETUP_CALLBACK(name, type) \
static std::vector<misc_update_function_t> &get_misc_##name##_functions() { \ static std::vector<misc_update_function_##type##_t> &get_misc_##name##_functions() { \
static std::vector<misc_update_function_t> functions; \ static std::vector<misc_update_function_##type##_t> functions; \
return functions; \ return functions; \
} \ } \
static void handle_misc_##name(unsigned char *obj) { \ static void handle_misc_##name(type *obj) { \
for (misc_update_function_t function : get_misc_##name##_functions()) { \ for (misc_update_function_##type##_t function : get_misc_##name##_functions()) { \
(*function)(obj); \ (*function)(obj); \
} \ } \
} \ } \
void misc_run_on_##name(misc_update_function_t function) { \ void misc_run_on_##name(misc_update_function_##type##_t function) { \
get_misc_##name##_functions().push_back(function); \ get_misc_##name##_functions().push_back(function); \
} }
// Run Functions On Update // Run Functions On Update
SETUP_CALLBACK(update); SETUP_CALLBACK(update, Minecraft);
// Handle Custom Update Behavior // Handle Custom Update Behavior
static void Minecraft_update_injection(unsigned char *minecraft) { static void Minecraft_update_injection(Minecraft *minecraft) {
// Call Original Method // Call Original Method
(*Minecraft_update)(minecraft); (*Minecraft_update_non_virtual)(minecraft);
// Run Functions // Run Functions
handle_misc_update(minecraft); handle_misc_update(minecraft);
} }
// Run Functions On Tick // Run Functions On Tick
SETUP_CALLBACK(tick); SETUP_CALLBACK(tick, Minecraft);
// Handle Custom Tick Behavior // Handle Custom Tick Behavior
static void Minecraft_tick_injection(unsigned char *minecraft, int32_t param_1, int32_t param_2) { static void Minecraft_tick_injection(Minecraft *minecraft, int32_t param_1, int32_t param_2) {
// Call Original Method // Call Original Method
(*Minecraft_tick)(minecraft, param_1, param_2); (*Minecraft_tick)(minecraft, param_1, param_2);
@ -44,11 +44,11 @@ static void Minecraft_tick_injection(unsigned char *minecraft, int32_t param_1,
} }
// Run Functions On Recipes Setup // Run Functions On Recipes Setup
SETUP_CALLBACK(recipes_setup); SETUP_CALLBACK(recipes_setup, Recipes);
// Handle Custom Recipes Setup Behavior // Handle Custom Recipes Setup Behavior
static unsigned char *Recipes_injection(unsigned char *recipes) { static Recipes *Recipes_injection(Recipes *recipes) {
// Call Original Method // Call Original Method
(*Recipes)(recipes); (*Recipes_constructor)(recipes);
// Run Functions // Run Functions
handle_misc_recipes_setup(recipes); handle_misc_recipes_setup(recipes);
@ -58,11 +58,11 @@ static unsigned char *Recipes_injection(unsigned char *recipes) {
} }
// Run Functions On Furnace Recipes Setup // Run Functions On Furnace Recipes Setup
SETUP_CALLBACK(furnace_recipes_setup); SETUP_CALLBACK(furnace_recipes_setup, FurnaceRecipes);
// Handle Custom Furnace Recipes Setup Behavior // Handle Custom Furnace Recipes Setup Behavior
static unsigned char *FurnaceRecipes_injection(unsigned char *recipes) { static FurnaceRecipes *FurnaceRecipes_injection(FurnaceRecipes *recipes) {
// Call Original Method // Call Original Method
(*FurnaceRecipes)(recipes); (*FurnaceRecipes_constructor)(recipes);
// Run Functions // Run Functions
handle_misc_furnace_recipes_setup(recipes); handle_misc_furnace_recipes_setup(recipes);
@ -72,9 +72,9 @@ static unsigned char *FurnaceRecipes_injection(unsigned char *recipes) {
} }
// Run Functions On Creative Inventory Setup // Run Functions On Creative Inventory Setup
SETUP_CALLBACK(creative_inventory_setup); SETUP_CALLBACK(creative_inventory_setup, FillingContainer);
// Handle Custom Creative Inventory Setup Behavior // Handle Custom Creative Inventory Setup Behavior
static void Inventory_setupDefault_FillingContainer_addItem_call_injection(unsigned char *filling_container, ItemInstance *item_instance) { static void Inventory_setupDefault_FillingContainer_addItem_call_injection(FillingContainer *filling_container, ItemInstance *item_instance) {
// Call Original Method // Call Original Method
(*FillingContainer_addItem)(filling_container, item_instance); (*FillingContainer_addItem)(filling_container, item_instance);
// Run Functions // Run Functions
@ -82,7 +82,7 @@ static void Inventory_setupDefault_FillingContainer_addItem_call_injection(unsig
} }
// Run Functions On Tiles Setup // Run Functions On Tiles Setup
SETUP_CALLBACK(tiles_setup); SETUP_CALLBACK(tiles_setup, void);
// Handle Custom Tiles Setup Behavior // Handle Custom Tiles Setup Behavior
static void Tile_initTiles_injection() { static void Tile_initTiles_injection() {
// Run Functions // Run Functions
@ -93,7 +93,7 @@ static void Tile_initTiles_injection() {
} }
// Run Functions On Items Setup // Run Functions On Items Setup
SETUP_CALLBACK(items_setup); SETUP_CALLBACK(items_setup, void);
// Handle Custom Items Setup Behavior // Handle Custom Items Setup Behavior
static void Item_initItems_injection() { static void Item_initItems_injection() {
// Run Functions // Run Functions
@ -106,12 +106,12 @@ static void Item_initItems_injection() {
// Init // Init
void _init_misc_api() { void _init_misc_api() {
// Handle Custom Update Behavior // Handle Custom Update Behavior
overwrite_calls((void *) Minecraft_update, (void *) Minecraft_update_injection); overwrite_calls((void *) Minecraft_update_non_virtual, (void *) Minecraft_update_injection);
// Handle Custom Tick Behavior // Handle Custom Tick Behavior
overwrite_calls((void *) Minecraft_tick, (void *) Minecraft_tick_injection); overwrite_calls((void *) Minecraft_tick, (void *) Minecraft_tick_injection);
// Handle Custom Recipe Setup Behavior // Handle Custom Recipe Setup Behavior
overwrite_calls((void *) Recipes, (void *) Recipes_injection); overwrite_calls((void *) Recipes_constructor, (void *) Recipes_injection);
overwrite_calls((void *) FurnaceRecipes, (void *) FurnaceRecipes_injection); overwrite_calls((void *) FurnaceRecipes_constructor, (void *) FurnaceRecipes_injection);
// Handle Custom Creative Inventory Setup Behavior // Handle Custom Creative Inventory Setup Behavior
overwrite_call((void *) 0x8e0fc, (void *) Inventory_setupDefault_FillingContainer_addItem_call_injection); overwrite_call((void *) 0x8e0fc, (void *) Inventory_setupDefault_FillingContainer_addItem_call_injection);
// Handle Custom Item/Tile Init Behavior // Handle Custom Item/Tile Init Behavior

View File

@ -8,11 +8,12 @@
// Print Chat To Log // Print Chat To Log
static bool Gui_addMessage_recursing = false; static bool Gui_addMessage_recursing = false;
static void Gui_addMessage_injection(unsigned char *gui, std::string const& text) { static void Gui_addMessage_injection(Gui *gui, std::string *text) {
// Sanitize Message // Sanitize Message
char *new_message = strdup(text.c_str()); char *new_message = strdup(text->c_str());
ALLOC_CHECK(new_message); ALLOC_CHECK(new_message);
sanitize_string(&new_message, -1, 1); sanitize_string(&new_message, -1, 1);
std::string cpp_str = new_message;
// Process Message // Process Message
if (!Gui_addMessage_recursing) { if (!Gui_addMessage_recursing) {
@ -25,28 +26,29 @@ static void Gui_addMessage_injection(unsigned char *gui, std::string const& text
free(safe_message); free(safe_message);
// Call Original Method // Call Original Method
(*Gui_addMessage)(gui, std::string(new_message)); (*Gui_addMessage)(gui, &cpp_str);
// End Recursing // End Recursing
Gui_addMessage_recursing = false; Gui_addMessage_recursing = false;
} else { } else {
// Call Original Method // Call Original Method
(*Gui_addMessage)(gui, std::string(new_message)); (*Gui_addMessage)(gui, &cpp_str);
} }
// Free // Free
free(new_message); free(new_message);
} }
void misc_add_message(unsigned char *gui, const char *text) { void misc_add_message(Gui *gui, const char *text) {
Gui_addMessage_injection(gui, text); std::string str = text;
Gui_addMessage_injection(gui, &str);
} }
// Print Progress Reports // Print Progress Reports
static int last_progress = -1; static int last_progress = -1;
static const char *last_message = NULL; static const char *last_message = NULL;
static void print_progress(unsigned char *minecraft) { static void print_progress(Minecraft *minecraft) {
const char *message = (*Minecraft_getProgressMessage)(minecraft); const char *message = (*Minecraft_getProgressMessage)(minecraft);
int32_t progress = *(int32_t *) (minecraft + Minecraft_progress_property_offset); int32_t progress = minecraft->progress;
if ((*Minecraft_isLevelGenerated)(minecraft)) { if ((*Minecraft_isLevelGenerated)(minecraft)) {
message = "Ready"; message = "Ready";
progress = -1; progress = -1;
@ -71,13 +73,13 @@ static void print_progress(unsigned char *minecraft) {
} }
// Print Progress Reports Regularly // Print Progress Reports Regularly
static void Minecraft_update_injection(unsigned char *minecraft) { static void Minecraft_update_injection(Minecraft *minecraft) {
// Print Progress Reports // Print Progress Reports
print_progress(minecraft); print_progress(minecraft);
} }
// Log When Game Is Saved // Log When Game Is Saved
void Level_saveLevelData_injection(unsigned char *level) { void Level_saveLevelData_injection(Level *level) {
// Print Log Message // Print Log Message
DEBUG("Saving Game"); DEBUG("Saving Game");

View File

@ -29,47 +29,47 @@
#define DEFAULT_BUBBLES_PADDING 1 #define DEFAULT_BUBBLES_PADDING 1
#define NUMBER_OF_SLOTS 9 #define NUMBER_OF_SLOTS 9
static int use_classic_hud = 0; static int use_classic_hud = 0;
static void Gui_renderHearts_GuiComponent_blit_hearts_injection(unsigned char *component, int32_t x_dest, int32_t y_dest, int32_t x_src, int32_t y_src, int32_t width_dest, int32_t height_dest, int32_t width_src, int32_t height_src) { static void Gui_renderHearts_GuiComponent_blit_hearts_injection(Gui *component, int32_t x_dest, int32_t y_dest, int32_t x_src, int32_t y_src, int32_t width_dest, int32_t height_dest, int32_t width_src, int32_t height_src) {
unsigned char *minecraft = *(unsigned char **) (component + Gui_minecraft_property_offset); Minecraft *minecraft = component->minecraft;
x_dest -= DEFAULT_HUD_PADDING; x_dest -= DEFAULT_HUD_PADDING;
float width = ((float) *(int32_t *) (minecraft + Minecraft_screen_width_property_offset)) * *InvGuiScale; float width = ((float) minecraft->screen_width) * *Gui_InvGuiScale;
float height = ((float) *(int32_t *) (minecraft + Minecraft_screen_height_property_offset)) * *InvGuiScale; float height = ((float) minecraft->screen_height) * *Gui_InvGuiScale;
x_dest += (width - (NUMBER_OF_SLOTS * SLOT_WIDTH)) / 2; x_dest += (width - (NUMBER_OF_SLOTS * SLOT_WIDTH)) / 2;
y_dest -= DEFAULT_HUD_PADDING; y_dest -= DEFAULT_HUD_PADDING;
y_dest += height - HUD_ELEMENT_HEIGHT - TOOLBAR_HEIGHT - NEW_HUD_PADDING; y_dest += height - HUD_ELEMENT_HEIGHT - TOOLBAR_HEIGHT - NEW_HUD_PADDING;
// Call Original Method // Call Original Method
(*GuiComponent_blit)(component, x_dest, y_dest, x_src, y_src, width_dest, height_dest, width_src, height_src); (*Gui_blit)(component, x_dest, y_dest, x_src, y_src, width_dest, height_dest, width_src, height_src);
} }
static void Gui_renderHearts_GuiComponent_blit_armor_injection(unsigned char *component, int32_t x_dest, int32_t y_dest, int32_t x_src, int32_t y_src, int32_t width_dest, int32_t height_dest, int32_t width_src, int32_t height_src) { static void Gui_renderHearts_GuiComponent_blit_armor_injection(Gui *component, int32_t x_dest, int32_t y_dest, int32_t x_src, int32_t y_src, int32_t width_dest, int32_t height_dest, int32_t width_src, int32_t height_src) {
unsigned char *minecraft = *(unsigned char **) (component + Gui_minecraft_property_offset); Minecraft *minecraft = component->minecraft;
x_dest -= DEFAULT_HUD_PADDING + HUD_ELEMENT_WIDTH; x_dest -= DEFAULT_HUD_PADDING + HUD_ELEMENT_WIDTH;
float width = ((float) *(int32_t *) (minecraft + Minecraft_screen_width_property_offset)) * *InvGuiScale; float width = ((float) minecraft->screen_width) * *Gui_InvGuiScale;
float height = ((float) *(int32_t *) (minecraft + Minecraft_screen_height_property_offset)) * *InvGuiScale; float height = ((float) minecraft->screen_height) * *Gui_InvGuiScale;
x_dest += width - ((width - (NUMBER_OF_SLOTS * SLOT_WIDTH)) / 2) - HUD_ELEMENT_WIDTH; x_dest += width - ((width - (NUMBER_OF_SLOTS * SLOT_WIDTH)) / 2) - HUD_ELEMENT_WIDTH;
y_dest -= DEFAULT_HUD_PADDING; y_dest -= DEFAULT_HUD_PADDING;
y_dest += height - HUD_ELEMENT_HEIGHT - TOOLBAR_HEIGHT - NEW_HUD_PADDING; y_dest += height - HUD_ELEMENT_HEIGHT - TOOLBAR_HEIGHT - NEW_HUD_PADDING;
// Call Original Method // Call Original Method
(*GuiComponent_blit)(component, x_dest, y_dest, x_src, y_src, width_dest, height_dest, width_src, height_src); (*Gui_blit)(component, x_dest, y_dest, x_src, y_src, width_dest, height_dest, width_src, height_src);
} }
static void Gui_renderBubbles_GuiComponent_blit_injection(unsigned char *component, int32_t x_dest, int32_t y_dest, int32_t x_src, int32_t y_src, int32_t width_dest, int32_t height_dest, int32_t width_src, int32_t height_src) { static void Gui_renderBubbles_GuiComponent_blit_injection(Gui *component, int32_t x_dest, int32_t y_dest, int32_t x_src, int32_t y_src, int32_t width_dest, int32_t height_dest, int32_t width_src, int32_t height_src) {
unsigned char *minecraft = *(unsigned char **) (component + Gui_minecraft_property_offset); Minecraft *minecraft = component->minecraft;
x_dest -= DEFAULT_HUD_PADDING; x_dest -= DEFAULT_HUD_PADDING;
float width = ((float) *(int32_t *) (minecraft + Minecraft_screen_width_property_offset)) * *InvGuiScale; float width = ((float) minecraft->screen_width) * *Gui_InvGuiScale;
float height = ((float) *(int32_t *) (minecraft + Minecraft_screen_height_property_offset)) * *InvGuiScale; float height = ((float) minecraft->screen_height) * *Gui_InvGuiScale;
x_dest += (width - (NUMBER_OF_SLOTS * SLOT_WIDTH)) / 2; x_dest += (width - (NUMBER_OF_SLOTS * SLOT_WIDTH)) / 2;
y_dest -= DEFAULT_HUD_PADDING + DEFAULT_BUBBLES_PADDING + HUD_ELEMENT_HEIGHT; y_dest -= DEFAULT_HUD_PADDING + DEFAULT_BUBBLES_PADDING + HUD_ELEMENT_HEIGHT;
y_dest += height - HUD_ELEMENT_HEIGHT - TOOLBAR_HEIGHT - HUD_ELEMENT_HEIGHT - NEW_HUD_PADDING; y_dest += height - HUD_ELEMENT_HEIGHT - TOOLBAR_HEIGHT - HUD_ELEMENT_HEIGHT - NEW_HUD_PADDING;
// Call Original Method // Call Original Method
(*GuiComponent_blit)(component, x_dest, y_dest, x_src, y_src, width_dest, height_dest, width_src, height_src); (*Gui_blit)(component, x_dest, y_dest, x_src, y_src, width_dest, height_dest, width_src, height_src);
} }
// Additional GUI Rendering // Additional GUI Rendering
static int hide_chat_messages = 0; static int hide_chat_messages = 0;
static int render_selected_item_text = 0; static int render_selected_item_text = 0;
static void Gui_renderChatMessages_injection(unsigned char *gui, int32_t y_offset, uint32_t max_messages, bool disable_fading, unsigned char *font) { static void Gui_renderChatMessages_injection(Gui *gui, int32_t y_offset, uint32_t max_messages, bool disable_fading, Font *font) {
// Handle Classic HUD // Handle Classic HUD
if (use_classic_hud) { if (use_classic_hud) {
unsigned char *minecraft = *(unsigned char **) (gui + Gui_minecraft_property_offset); Minecraft *minecraft = gui->minecraft;
if (!(*Minecraft_isCreativeMode)(minecraft)) { if (!(*Minecraft_isCreativeMode)(minecraft)) {
y_offset -= (HUD_ELEMENT_HEIGHT * 2) + NEW_HUD_PADDING; y_offset -= (HUD_ELEMENT_HEIGHT * 2) + NEW_HUD_PADDING;
} }
@ -85,22 +85,22 @@ static void Gui_renderChatMessages_injection(unsigned char *gui, int32_t y_offse
// Fix GL Mode // Fix GL Mode
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Calculate Selected Item Text Scale // Calculate Selected Item Text Scale
unsigned char *minecraft = *(unsigned char **) (gui + Gui_minecraft_property_offset); Minecraft *minecraft = gui->minecraft;
int32_t screen_width = *(int32_t *) (minecraft + Minecraft_screen_width_property_offset); int32_t screen_width = minecraft->screen_width;
float scale = ((float) screen_width) * *InvGuiScale; float scale = ((float) screen_width) * *Gui_InvGuiScale;
// Render Selected Item Text // Render Selected Item Text
(*Gui_renderOnSelectItemNameText)(gui, (int32_t) scale, font, y_offset - 0x13); (*Gui_renderOnSelectItemNameText)(gui, (int32_t) scale, font, y_offset - 0x13);
} }
} }
// Reset Selected Item Text Timer On Slot Select // Reset Selected Item Text Timer On Slot Select
static uint32_t reset_selected_item_text_timer = 0; static uint32_t reset_selected_item_text_timer = 0;
static void Gui_tick_injection(unsigned char *gui) { static void Gui_tick_injection(Gui *gui) {
// Call Original Method // Call Original Method
(*Gui_tick)(gui); (*Gui_tick)(gui);
// Handle Reset // Handle Reset
if (render_selected_item_text) { if (render_selected_item_text) {
float *selected_item_text_timer = (float *) (gui + Gui_selected_item_text_timer_property_offset); float *selected_item_text_timer = &gui->selected_item_text_timer;
if (reset_selected_item_text_timer) { if (reset_selected_item_text_timer) {
// Reset // Reset
*selected_item_text_timer = 0; *selected_item_text_timer = 0;
@ -109,7 +109,7 @@ static void Gui_tick_injection(unsigned char *gui) {
} }
} }
// Trigger Reset Selected Item Text Timer On Slot Select // Trigger Reset Selected Item Text Timer On Slot Select
static void Inventory_selectSlot_injection(unsigned char *inventory, int32_t slot) { static void Inventory_selectSlot_injection(Inventory *inventory, int32_t slot) {
// Call Original Method // Call Original Method
(*Inventory_selectSlot)(inventory, slot); (*Inventory_selectSlot)(inventory, slot);
@ -120,7 +120,7 @@ static void Inventory_selectSlot_injection(unsigned char *inventory, int32_t slo
} }
// Translucent Toolbar // Translucent Toolbar
static void Gui_renderToolBar_injection(unsigned char *gui, float param_1, int32_t param_2, int32_t param_3) { static void Gui_renderToolBar_injection(Gui *gui, float param_1, int32_t param_2, int32_t param_3) {
// Call Original Method // Call Original Method
int was_blend_enabled = glIsEnabled(GL_BLEND); int was_blend_enabled = glIsEnabled(GL_BLEND);
if (!was_blend_enabled) { if (!was_blend_enabled) {
@ -138,24 +138,24 @@ static void Gui_renderToolBar_glColor4f_injection(GLfloat red, GLfloat green, GL
} }
// Fix Screen Rendering When GUI is Hidden // Fix Screen Rendering When GUI is Hidden
static void Screen_render_injection(unsigned char *screen, int32_t param_1, int32_t param_2, float param_3) { static void Screen_render_injection(Screen *screen, int32_t param_1, int32_t param_2, float param_3) {
// Fix // Fix
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Call Original Method // Call Original Method
(*Screen_render)(screen, param_1, param_2, param_3); (*Screen_render_non_virtual)(screen, param_1, param_2, param_3);
} }
// Sanitize Username // Sanitize Username
#define MAX_USERNAME_LENGTH 16 #define MAX_USERNAME_LENGTH 16
static void LoginPacket_read_injection(unsigned char *packet, unsigned char *bit_stream) { static void LoginPacket_read_injection(LoginPacket *packet, unsigned char *bit_stream) {
// Call Original Method // Call Original Method
(*LoginPacket_read)(packet, bit_stream); (*LoginPacket_read_non_virtual)(packet, bit_stream);
// Prepare // Prepare
unsigned char *rak_string = packet + LoginPacket_username_property_offset; RakNet_RakString *rak_string = &packet->username;
// Get Original Username // Get Original Username
unsigned char *shared_string = *(unsigned char **) (rak_string + RakNet_RakString_sharedString_property_offset); RakNet_RakString_SharedString *shared_string = rak_string->sharedString;
char *c_str = *(char **) (shared_string + RakNet_RakString_SharedString_c_str_property_offset); char *c_str = shared_string->c_str;
// Sanitize // Sanitize
char *new_username = strdup(c_str); char *new_username = strdup(c_str);
ALLOC_CHECK(new_username); ALLOC_CHECK(new_username);
@ -171,9 +171,9 @@ static void LoginPacket_read_injection(unsigned char *packet, unsigned char *bit
// RakNet::RakString's format constructor is often given unsanitized user input and is never used for formatting, // RakNet::RakString's format constructor is often given unsanitized user input and is never used for formatting,
// this is a massive security risk, allowing clients to run arbitrary format specifiers, this disables the // this is a massive security risk, allowing clients to run arbitrary format specifiers, this disables the
// formatting functionality. // formatting functionality.
static unsigned char *RakNet_RakString_injection(unsigned char *rak_string, const char *format, ...) { static RakNet_RakString *RakNet_RakString_injection(RakNet_RakString *rak_string, const char *format, ...) {
// Call Original Method // Call Original Method
return (*RakNet_RakString)(rak_string, "%s", format); return (*RakNet_RakString_constructor)(rak_string, "%s", format);
} }
// Print Error Message If RakNet Startup Fails // Print Error Message If RakNet Startup Fails
@ -196,9 +196,9 @@ static char *RAKNET_ERROR_NAMES[] = {
#else #else
#define PRINT_RAKNET_STARTUP_FAILURE WARN #define PRINT_RAKNET_STARTUP_FAILURE WARN
#endif #endif
static RakNet_StartupResult RakNetInstance_host_RakNet_RakPeer_Startup_injection(unsigned char *rak_peer, unsigned short maxConnections, unsigned char *socketDescriptors, uint32_t socketDescriptorCount, int32_t threadPriority) { static RakNet_StartupResult RakNetInstance_host_RakNet_RakPeer_Startup_injection(RakNet_RakPeer *rak_peer, unsigned short maxConnections, unsigned char *socketDescriptors, uint32_t socketDescriptorCount, int32_t threadPriority) {
// Call Original Method // Call Original Method
RakNet_StartupResult result = (*RakNet_RakPeer_Startup)(rak_peer, maxConnections, socketDescriptors, socketDescriptorCount, threadPriority); RakNet_StartupResult result = rak_peer->vtable->Startup(rak_peer, maxConnections, socketDescriptors, socketDescriptorCount, threadPriority);
// Print Error // Print Error
if (result != RAKNET_STARTED) { if (result != RAKNET_STARTED) {
@ -210,32 +210,30 @@ static RakNet_StartupResult RakNetInstance_host_RakNet_RakPeer_Startup_injection
} }
// 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
static unsigned char *RakNetInstance_injection(unsigned char *rak_net_instance) { static RakNetInstance *RakNetInstance_injection(RakNetInstance *rak_net_instance) {
// Call Original Method // Call Original Method
unsigned char *result = (*RakNetInstance)(rak_net_instance); RakNetInstance *result = (*RakNetInstance_constructor)(rak_net_instance);
// Fix // Fix
*(unsigned char *) (rak_net_instance + RakNetInstance_pinging_for_hosts_property_offset) = 0; rak_net_instance->pinging_for_hosts = 0;
// Return // Return
return result; return result;
} }
// Close Current Screen On Death To Prevent Bugs // Close Current Screen On Death To Prevent Bugs
static void LocalPlayer_die_injection(unsigned char *entity, unsigned char *cause) { static void LocalPlayer_die_injection(LocalPlayer *entity, Entity *cause) {
// Close Screen // Close Screen
unsigned char *minecraft = *(unsigned char **) (entity + LocalPlayer_minecraft_property_offset); Minecraft *minecraft = entity->minecraft;
(*Minecraft_setScreen)(minecraft, NULL); (*Minecraft_setScreen)(minecraft, NULL);
// Call Original Method // Call Original Method
(*LocalPlayer_die)(entity, cause); (*LocalPlayer_die_non_virtual)(entity, cause);
} }
// Fix Furnace Not Checking Item Auxiliary When Inserting New Item // 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) { static int32_t FurnaceScreen_handleAddItem_injection(FurnaceScreen *furnace_screen, int32_t slot, ItemInstance *item) {
// Get Existing Item // Get Existing Item
unsigned char *tile_entity = *(unsigned char **) (furnace_screen + FurnaceScreen_tile_entity_property_offset); FurnaceTileEntity *tile_entity = furnace_screen->tile_entity;
unsigned char *tile_entity_vtable = *(unsigned char **) tile_entity; ItemInstance *existing_item = tile_entity->vtable->getItem(tile_entity, slot);
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 // Check Item
int valid; int valid;
@ -268,7 +266,7 @@ static int32_t FurnaceScreen_handleAddItem_injection(unsigned char *furnace_scre
// The default behavior for Touch GUI is to only render the cursor when the mouse is clicking, this fixes that. // The default behavior for Touch GUI is to only render the cursor when the mouse is clicking, this fixes that.
// This also makes the cursor always render if the mouse is unlocked, instead of just when there is a Screen showing. // This also makes the cursor always render if the mouse is unlocked, instead of just when there is a Screen showing.
#ifndef MCPI_HEADLESS_MODE #ifndef MCPI_HEADLESS_MODE
static void GameRenderer_render_injection(unsigned char *game_renderer, float param_1) { static void GameRenderer_render_injection(GameRenderer *game_renderer, float param_1) {
// Call Original Method // Call Original Method
(*GameRenderer_render)(game_renderer, param_1); (*GameRenderer_render)(game_renderer, param_1);
@ -277,25 +275,25 @@ static void GameRenderer_render_injection(unsigned char *game_renderer, float pa
// Fix GL Mode // Fix GL Mode
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Get X And Y // Get X And Y
float x = (*Mouse_getX)() * (*InvGuiScale); float x = (*Mouse_getX)() * (*Gui_InvGuiScale);
float y = (*Mouse_getY)() * (*InvGuiScale); float y = (*Mouse_getY)() * (*Gui_InvGuiScale);
// Render Cursor // Render Cursor
unsigned char *minecraft = *(unsigned char **) (game_renderer + GameRenderer_minecraft_property_offset); Minecraft *minecraft = game_renderer->minecraft;
(*renderCursor)(x, y, minecraft); (*Common_renderCursor)(x, y, minecraft);
} }
} }
#endif #endif
// Get Real Selected Slot // Get Real Selected Slot
int32_t misc_get_real_selected_slot(unsigned char *player) { int32_t misc_get_real_selected_slot(Player *player) {
// Get Selected Slot // Get Selected Slot
unsigned char *inventory = *(unsigned char **) (player + Player_inventory_property_offset); Inventory *inventory = player->inventory;
int32_t selected_slot = *(int32_t *) (inventory + Inventory_selectedSlot_property_offset); int32_t selected_slot = inventory->selectedSlot;
// Linked Slots // Linked Slots
int32_t linked_slots_length = *(int32_t *) (inventory + FillingContainer_linked_slots_length_property_offset); int32_t linked_slots_length = inventory->linked_slots_length;
if (selected_slot < linked_slots_length) { if (selected_slot < linked_slots_length) {
int32_t *linked_slots = *(int32_t **) (inventory + FillingContainer_linked_slots_property_offset); int32_t *linked_slots = inventory->linked_slots;
selected_slot = linked_slots[selected_slot]; selected_slot = linked_slots[selected_slot];
} }
@ -311,10 +309,10 @@ static void anGenBuffers_injection(int32_t count, uint32_t *buffers) {
#endif #endif
// Fix Graphics Bug When Switching To First-Person While Sneaking // Fix Graphics Bug When Switching To First-Person While Sneaking
static void HumanoidMobRenderer_render_injection(unsigned char *model_renderer, unsigned char *entity, float param_2, float param_3, float param_4, float param_5, float param_6) { static void HumanoidMobRenderer_render_injection(HumanoidMobRenderer *model_renderer, Entity *entity, float param_2, float param_3, float param_4, float param_5, float param_6) {
(*HumanoidMobRenderer_render)(model_renderer, entity, param_2, param_3, param_4, param_5, param_6); (*HumanoidMobRenderer_render_non_virtual)(model_renderer, entity, param_2, param_3, param_4, param_5, param_6);
unsigned char *model = *(unsigned char **) (model_renderer + HumanoidMobRenderer_model_property_offset); HumanoidModel *model = model_renderer->model;
*(bool *) (model + HumanoidModel_is_sneaking_property_offset) = 0; model->is_sneaking = 0;
} }
// Custom API Port // Custom API Port
@ -337,17 +335,15 @@ HOOK(bind, int, (int sockfd, const struct sockaddr *addr, socklen_t addrlen)) {
} }
// Change Grass Color // Change Grass Color
static int32_t get_color(unsigned char *level_source, int32_t x, int32_t z) { static int32_t get_color(LevelSource *level_source, int32_t x, int32_t z) {
unsigned char *level_source_vtable = *(unsigned char **) level_source; Biome *biome = level_source->vtable->getBiome(level_source, x, z);
LevelSource_getBiome_t LevelSource_getBiome = *(LevelSource_getBiome_t *) (level_source_vtable + LevelSource_getBiome_vtable_offset);
unsigned char *biome = (*LevelSource_getBiome)(level_source, x, z);
if (biome == NULL) { if (biome == NULL) {
return 0; return 0;
} }
return *(int32_t *) (biome + Biome_color_property_offset); return biome->color;
} }
#define BIOME_BLEND_SIZE 7 #define BIOME_BLEND_SIZE 7
static int32_t GrassTile_getColor_injection(__attribute__((unused)) unsigned char *tile, unsigned char *level_source, int32_t x, __attribute__((unused)) int32_t y, int32_t z) { static int32_t GrassTile_getColor_injection(__attribute__((unused)) Tile *tile, LevelSource *level_source, int32_t x, __attribute__((unused)) int32_t y, int32_t z) {
int r_sum = 0; int r_sum = 0;
int g_sum = 0; int g_sum = 0;
int b_sum = 0; int b_sum = 0;
@ -368,30 +364,28 @@ static int32_t GrassTile_getColor_injection(__attribute__((unused)) unsigned cha
int b_avg = b_sum / color_sum; int b_avg = b_sum / color_sum;
return (r_avg << 16) | (g_avg << 8) | b_avg; return (r_avg << 16) | (g_avg << 8) | b_avg;
} }
static int32_t TallGrass_getColor_injection(unsigned char *tile, unsigned char *level_source, int32_t x, int32_t y, int32_t z) { static int32_t TallGrass_getColor_injection(TallGrass *tile, LevelSource *level_source, int32_t x, int32_t y, int32_t z) {
int32_t original_color = (*TallGrass_getColor)(tile, level_source, x, y, z); int32_t original_color = (*TallGrass_getColor_non_virtual)(tile, level_source, x, y, z);
if (original_color == 0x339933) { if (original_color == 0x339933) {
return GrassTile_getColor_injection(tile, level_source, x, y, z); return GrassTile_getColor_injection((Tile *) tile, level_source, x, y, z);
} else { } else {
return original_color; return original_color;
} }
} }
// Generate Caves // Generate Caves
static void RandomLevelSource_buildSurface_injection(unsigned char *random_level_source, int32_t chunk_x, int32_t chunk_y, unsigned char *chunk_data, unsigned char **biomes) { static void RandomLevelSource_buildSurface_injection(RandomLevelSource *random_level_source, int32_t chunk_x, int32_t chunk_y, unsigned char *chunk_data, Biome **biomes) {
// Call Original Method // Call Original Method
(*RandomLevelSource_buildSurface)(random_level_source, chunk_x, chunk_y, chunk_data, biomes); (*RandomLevelSource_buildSurface)(random_level_source, chunk_x, chunk_y, chunk_data, biomes);
// Get Level // Get Level
unsigned char *level = *(unsigned char **) (random_level_source + RandomLevelSource_level_property_offset); Level *level = random_level_source->level;
// Get Cave Feature // Get Cave Feature
unsigned char *cave_feature = random_level_source + RandomLevelSource_cave_feature_property_offset; LargeCaveFeature *cave_feature = &random_level_source->cave_feature;
unsigned char *cave_feature_vtable = *(unsigned char **) cave_feature;
// Generate // Generate
LargeFeature_apply_t LargeCaveFeature_apply = *(LargeFeature_apply_t *) (cave_feature_vtable + LargeFeature_apply_vtable_offset); cave_feature->vtable->apply(cave_feature, (ChunkSource *) random_level_source, level, chunk_x, chunk_y, chunk_data, 0);
(*LargeCaveFeature_apply)(cave_feature, random_level_source, level, chunk_x, chunk_y, chunk_data, 0);
} }
// No Block Tinting // No Block Tinting
@ -400,18 +394,21 @@ static int32_t Tile_getColor_injection() {
} }
// Disable Hostile AI In Creative Mode // Disable Hostile AI In Creative Mode
static unsigned char *PathfinderMob_findAttackTarget_injection(unsigned char *mob) { #define has_vtable(obj, type) (((void *) obj->vtable) == type##_vtable_base)
static Entity *PathfinderMob_findAttackTarget_injection(PathfinderMob *mob) {
// Call Original Method // Call Original Method
unsigned char *mob_vtable = *(unsigned char **) mob; Entity *target = mob->vtable->findAttackTarget(mob);
PathfinderMob_findAttackTarget_t PathfinderMob_findAttackTarget = *(PathfinderMob_findAttackTarget_t *) (mob_vtable + PathfinderMob_findAttackTarget_vtable_offset);
unsigned char *target = (*PathfinderMob_findAttackTarget)(mob);
// Check If Creative Mode // Check If Creative Mode
if (target != NULL) { if (target != NULL) {
unsigned char *inventory = *(unsigned char **) (target + Player_inventory_property_offset); bool is_player = has_vtable(target, Player) || has_vtable(target, LocalPlayer) || has_vtable(target, ServerPlayer) || has_vtable(target, RemotePlayer);
bool is_creative = *(bool *) (inventory + FillingContainer_is_creative_property_offset); if (is_player) {
if (is_creative) { Player *player = (Player *) target;
target = NULL; Inventory *inventory = player->inventory;
bool is_creative = inventory->is_creative;
if (is_creative) {
target = NULL;
}
} }
} }
@ -420,29 +417,27 @@ static unsigned char *PathfinderMob_findAttackTarget_injection(unsigned char *mo
} }
// 3D Chests // 3D Chests
static int32_t Tile_getRenderShape_injection(unsigned char *tile) { static int32_t Tile_getRenderShape_injection(Tile *tile) {
if (tile == *Tile_chest) { if (tile == *Tile_chest) {
// Don't Render "Simple" Chest Model // Don't Render "Simple" Chest Model
return -1; return -1;
} else { } else {
// Call Original Method // Call Original Method
unsigned char *tile_vtable = *(unsigned char **) tile; return tile->vtable->getRenderShape(tile);
Tile_getRenderShape_t Tile_getRenderShape = *(Tile_getRenderShape_t *) (tile_vtable + Tile_getRenderShape_vtable_offset);
return (*Tile_getRenderShape)(tile);
} }
} }
static unsigned char *ChestTileEntity_injection(unsigned char *tile_entity) { static ChestTileEntity *ChestTileEntity_injection(ChestTileEntity *tile_entity) {
// Call Original Method // Call Original Method
(*ChestTileEntity)(tile_entity); (*ChestTileEntity_constructor)(tile_entity);
// Enable Renderer // Enable Renderer
*(int32_t *) (tile_entity + TileEntity_renderer_id_property_offset) = 1; tile_entity->renderer_id = 1;
// Return // Return
return tile_entity; return tile_entity;
} }
static bool is_rendering_chest = 0; static bool is_rendering_chest = 0;
static void ModelPart_render_injection(unsigned char *model_part, float scale) { static void ModelPart_render_injection(ModelPart *model_part, float scale) {
// Start // Start
is_rendering_chest = 1; is_rendering_chest = 1;
@ -452,7 +447,7 @@ static void ModelPart_render_injection(unsigned char *model_part, float scale) {
// Stop // Stop
is_rendering_chest = 0; is_rendering_chest = 0;
} }
static void Tesselator_vertexUV_injection(unsigned char *tesselator, float x, float y, float z, float u, float v) { static void Tesselator_vertexUV_injection(Tesselator *tesselator, float x, float y, float z, float u, float v) {
// Fix Chest Texture // Fix Chest Texture
if (is_rendering_chest) { if (is_rendering_chest) {
v /= 2; v /= 2;
@ -466,35 +461,31 @@ static bool ChestTileEntity_shouldSave_injection(__attribute__((unused)) unsigne
} }
// Animated 3D Chest // Animated 3D Chest
static unsigned char *ContainerMenu_injection(unsigned char *container_menu, unsigned char *container, int32_t param_1) { static ContainerMenu *ContainerMenu_injection(ContainerMenu *container_menu, Container *container, int32_t param_1) {
// Call Original Method // Call Original Method
(*ContainerMenu)(container_menu, container, param_1); (*ContainerMenu_constructor)(container_menu, container, param_1);
// Play Animation // Play Animation
unsigned char *tile_entity = container - ChestTileEntity_container_property_offset; ChestTileEntity *tile_entity = (ChestTileEntity *) (((unsigned char *) container) - offsetof(ChestTileEntity, container));
bool is_client = *(bool *) (tile_entity + TileEntity_is_client_property_offset); bool is_client = tile_entity->is_client;
if (!is_client) { if (!is_client) {
unsigned char *container_vtable = *(unsigned char **) container; container->vtable->startOpen(container);
Container_startOpen_t Container_startOpen = *(Container_startOpen_t *) (container_vtable + Container_startOpen_vtable_offset);
(*Container_startOpen)(container);
} }
// Return // Return
return container_menu; return container_menu;
} }
static unsigned char *ContainerMenu_destructor_injection(unsigned char *container_menu) { static unsigned char *ContainerMenu_destructor_injection(ContainerMenu *container_menu) {
// Play Animation // Play Animation
unsigned char *container = *(unsigned char **) (container_menu + ContainerMenu_container_property_offset); Container *container = container_menu->container;
unsigned char *tile_entity = container - ChestTileEntity_container_property_offset; ChestTileEntity *tile_entity = (ChestTileEntity *) (((unsigned char *) container) - offsetof(ChestTileEntity, container));
bool is_client = *(bool *) (tile_entity + TileEntity_is_client_property_offset); bool is_client = tile_entity->is_client;
if (!is_client) { if (!is_client) {
unsigned char *container_vtable = *(unsigned char **) container; container->vtable->stopOpen(container);
Container_stopOpen_t Container_stopOpen = *(Container_stopOpen_t *) (container_vtable + Container_stopOpen_vtable_offset);
(*Container_stopOpen)(container);
} }
// Call Original Method // Call Original Method
return (*ContainerMenu_destructor)(container_menu); return (*ContainerMenu_destructor_non_virtual)(container_menu);
} }
#ifndef MCPI_HEADLESS_MODE #ifndef MCPI_HEADLESS_MODE
@ -511,7 +502,7 @@ static void glColor4f_injection(__attribute__((unused)) GLfloat red, __attribute
line_width = strtof(custom_line_width, NULL); line_width = strtof(custom_line_width, NULL);
} else { } else {
// Guess // Guess
line_width = 2 / (*InvGuiScale); line_width = 2 / (*Gui_InvGuiScale);
} }
// Clamp Line Width // Clamp Line Width
float range[2]; float range[2];
@ -560,19 +551,19 @@ void init_misc() {
} }
// Fix Screen Rendering When GUI is Hidden // Fix Screen Rendering When GUI is Hidden
overwrite_calls((void *) Screen_render, (void *) Screen_render_injection); overwrite_calls((void *) Screen_render_non_virtual, (void *) Screen_render_injection);
// Sanitize Username // Sanitize Username
patch_address(LoginPacket_read_vtable_addr, (void *) LoginPacket_read_injection); patch_address(LoginPacket_read_vtable_addr, (void *) LoginPacket_read_injection);
// Fix RakNet::RakString Security Bug // Fix RakNet::RakString Security Bug
overwrite_calls((void *) RakNet_RakString, (void *) RakNet_RakString_injection); overwrite_calls((void *) RakNet_RakString_constructor, (void *) RakNet_RakString_injection);
// Print Error Message If RakNet Startup Fails // Print Error Message If RakNet Startup Fails
overwrite_call((void *) 0x73778, (void *) RakNetInstance_host_RakNet_RakPeer_Startup_injection); overwrite_call((void *) 0x73778, (void *) RakNetInstance_host_RakNet_RakPeer_Startup_injection);
// 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
overwrite_calls((void *) RakNetInstance, (void *) RakNetInstance_injection); overwrite_calls((void *) RakNetInstance_constructor, (void *) RakNetInstance_injection);
// Close Current Screen On Death To Prevent Bugs // Close Current Screen On Death To Prevent Bugs
if (feature_has("Close Current Screen On Death", server_disabled)) { if (feature_has("Close Current Screen On Death", server_disabled)) {
@ -613,12 +604,12 @@ void init_misc() {
// Remove Forced GUI Lag // Remove Forced GUI Lag
if (feature_has("Remove Forced GUI Lag (Can Break Joining Servers)", server_enabled)) { if (feature_has("Remove Forced GUI Lag (Can Break Joining Servers)", server_enabled)) {
overwrite_calls((void *) sleepMs, (void *) nop); overwrite_calls((void *) Common_sleepMs, (void *) nop);
} }
#ifndef MCPI_HEADLESS_MODE #ifndef MCPI_HEADLESS_MODE
// Properly Generate Buffers // Properly Generate Buffers
overwrite((void *) anGenBuffers, (void *) anGenBuffers_injection); overwrite((void *) Common_anGenBuffers, (void *) anGenBuffers_injection);
#endif #endif
// Fix Graphics Bug When Switching To First-Person While Sneaking // Fix Graphics Bug When Switching To First-Person While Sneaking
@ -653,7 +644,7 @@ void init_misc() {
patch_address((void *) TallGrass_getColor_vtable_addr, (void *) Tile_getColor_injection); patch_address((void *) TallGrass_getColor_vtable_addr, (void *) Tile_getColor_injection);
patch_address((void *) StemTile_getColor_vtable_addr, (void *) Tile_getColor_injection); patch_address((void *) StemTile_getColor_vtable_addr, (void *) Tile_getColor_injection);
patch_address((void *) LeafTile_getColor_vtable_addr, (void *) Tile_getColor_injection); patch_address((void *) LeafTile_getColor_vtable_addr, (void *) Tile_getColor_injection);
overwrite((void *) LiquidTile_getColor, (void *) Tile_getColor_injection); overwrite((void *) LiquidTile_getColor_non_virtual, (void *) Tile_getColor_injection);
} }
// Custom GUI Scale // Custom GUI Scale
@ -676,7 +667,7 @@ void init_misc() {
// 3D Chests // 3D Chests
if (feature_has("3D Chest Model", server_disabled)) { if (feature_has("3D Chest Model", server_disabled)) {
overwrite_call((void *) 0x5e830, (void *) Tile_getRenderShape_injection); overwrite_call((void *) 0x5e830, (void *) Tile_getRenderShape_injection);
overwrite_calls((void *) ChestTileEntity, (void *) ChestTileEntity_injection); overwrite_calls((void *) ChestTileEntity_constructor, (void *) ChestTileEntity_injection);
overwrite_call((void *) 0x6655c, (void *) ModelPart_render_injection); overwrite_call((void *) 0x6655c, (void *) ModelPart_render_injection);
overwrite_call((void *) 0x66568, (void *) ModelPart_render_injection); overwrite_call((void *) 0x66568, (void *) ModelPart_render_injection);
overwrite_call((void *) 0x66574, (void *) ModelPart_render_injection); overwrite_call((void *) 0x66574, (void *) ModelPart_render_injection);
@ -687,8 +678,8 @@ void init_misc() {
patch((void *) 0x66404, chest_color_patch); patch((void *) 0x66404, chest_color_patch);
// Animation // Animation
overwrite_calls((void *) ContainerMenu, (void *) ContainerMenu_injection); overwrite_calls((void *) ContainerMenu_constructor, (void *) ContainerMenu_injection);
overwrite_calls((void *) ContainerMenu_destructor, (void *) ContainerMenu_destructor_injection); overwrite_calls((void *) ContainerMenu_destructor_non_virtual, (void *) ContainerMenu_destructor_injection);
patch_address(ContainerMenu_destructor_vtable_addr, (void *) ContainerMenu_destructor_injection); patch_address(ContainerMenu_destructor_vtable_addr, (void *) ContainerMenu_destructor_injection);
} }
patch_address((void *) 0x115b48, (void *) ChestTileEntity_shouldSave_injection); patch_address((void *) 0x115b48, (void *) ChestTileEntity_shouldSave_injection);

View File

@ -12,7 +12,7 @@
#include <mods/misc/misc.h> #include <mods/misc/misc.h>
// Read Asset File // Read Asset File
static AppPlatform_readAssetFile_return_value AppPlatform_readAssetFile_injection(__attribute__((unused)) unsigned char *app_platform, std::string const& path) { static AppPlatform_readAssetFile_return_value AppPlatform_readAssetFile_injection(__attribute__((unused)) AppPlatform *app_platform, std::string const& path) {
// Open File // Open File
std::ifstream stream("data/" + path, std::ios_base::binary | std::ios_base::ate); std::ifstream stream("data/" + path, std::ios_base::binary | std::ios_base::ate);
if (!stream) { if (!stream) {
@ -36,21 +36,19 @@ static AppPlatform_readAssetFile_return_value AppPlatform_readAssetFile_injectio
} }
// Add Missing Buttons To Pause Menu // Add Missing Buttons To Pause Menu
static void PauseScreen_init_injection(unsigned char *screen) { static void PauseScreen_init_injection(PauseScreen *screen) {
// Call Original Method // Call Original Method
(*PauseScreen_init)(screen); (*PauseScreen_init_non_virtual)(screen);
// Check If Server // Check If Server
unsigned char *minecraft = *(unsigned char **) (screen + Screen_minecraft_property_offset); Minecraft *minecraft = screen->minecraft;
unsigned char *rak_net_instance = *(unsigned char **) (minecraft + Minecraft_rak_net_instance_property_offset); RakNetInstance *rak_net_instance = minecraft->rak_net_instance;
if (rak_net_instance != NULL) { if (rak_net_instance != NULL) {
unsigned char *rak_net_instance_vtable = *(unsigned char**) rak_net_instance; if (rak_net_instance->vtable->isServer(rak_net_instance)) {
RakNetInstance_isServer_t RakNetInstance_isServer = *(RakNetInstance_isServer_t *) (rak_net_instance_vtable + RakNetInstance_isServer_vtable_offset);
if ((*RakNetInstance_isServer)(rak_net_instance)) {
// Add Button // Add Button
std::vector<unsigned char *> *rendered_buttons = (std::vector<unsigned char *> *) (screen + Screen_rendered_buttons_property_offset); std::vector<Button *> *rendered_buttons = &screen->rendered_buttons;
std::vector<unsigned char *> *selectable_buttons = (std::vector<unsigned char *> *) (screen + Screen_selectable_buttons_property_offset); std::vector<Button *> *selectable_buttons = &screen->selectable_buttons;
unsigned char *button = *(unsigned char **) (screen + PauseScreen_server_visibility_button_property_offset); Button *button = screen->server_visibility_button;
rendered_buttons->push_back(button); rendered_buttons->push_back(button);
selectable_buttons->push_back(button); selectable_buttons->push_back(button);
@ -64,7 +62,7 @@ static void PauseScreen_init_injection(unsigned char *screen) {
void _init_misc_cpp() { void _init_misc_cpp() {
// Implement AppPlatform::readAssetFile So Translations Work // Implement AppPlatform::readAssetFile So Translations Work
if (feature_has("Load Language Files", server_enabled)) { if (feature_has("Load Language Files", server_enabled)) {
overwrite((void *) AppPlatform_readAssetFile, (void *) AppPlatform_readAssetFile_injection); overwrite((void *) *AppPlatform_readAssetFile_vtable_addr, (void *) AppPlatform_readAssetFile_injection);
} }
// Fix Pause Menu // Fix Pause Menu

View File

@ -113,16 +113,16 @@ static void iterate_servers(std::function<void(const char *address, int port)> c
} }
// Ping External Servers // Ping External Servers
static void RakNetInstance_pingForHosts_injection(unsigned char *rak_net_instance, int32_t base_port) { static void RakNetInstance_pingForHosts_injection(RakNetInstance *rak_net_instance, int32_t base_port) {
// Call Original Method // Call Original Method
(*RakNetInstance_pingForHosts)(rak_net_instance, base_port); (*RakNetInstance_pingForHosts_non_virtual)(rak_net_instance, base_port);
// Get RakNet::RakPeer // Get RakNet::RakPeer
unsigned char *rak_peer = *(unsigned char **) (rak_net_instance + RakNetInstance_peer_property_offset); RakNet_RakPeer *rak_peer = rak_net_instance->peer;
// Add External Servers // Add External Servers
iterate_servers([rak_peer](const char *address, int port) { iterate_servers([rak_peer](const char *address, int port) {
(*RakNet_RakPeer_Ping)(rak_peer, address, port, 1, 0); rak_peer->vtable->Ping(rak_peer, address, port, 1, 0);
}); });
} }

View File

@ -1,11 +1,13 @@
#pragma once #pragma once
#include <symbols/minecraft.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
__attribute__((visibility("internal"))) void _init_options_cpp(); __attribute__((visibility("internal"))) void _init_options_cpp();
__attribute__((visibility("internal"))) extern unsigned char *stored_options; __attribute__((visibility("internal"))) extern Options *stored_options;
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -46,35 +46,35 @@ __attribute__((destructor)) static void _free_safe_username() {
static int render_distance; static int render_distance;
// Configure Options // Configure Options
unsigned char *stored_options = NULL; Options *stored_options = NULL;
static void Options_initDefaultValue_injection(unsigned char *options) { static void Options_initDefaultValue_injection(Options *options) {
// Call Original Method // Call Original Method
(*Options_initDefaultValue)(options); (*Options_initDefaultValue)(options);
// Default Graphics Settings // Default Graphics Settings
#ifndef MCPI_SERVER_MODE #ifndef MCPI_SERVER_MODE
*(options + Options_fancy_graphics_property_offset) = 1; options->fancy_graphics = 1;
*(options + Options_ambient_occlusion_property_offset) = 1; options->ambient_occlusion = 1;
#endif #endif
// Store // Store
stored_options = options; stored_options = options;
} }
static void Minecraft_init_injection(unsigned char *minecraft) { static void Minecraft_init_injection(Minecraft *minecraft) {
// Call Original Method // Call Original Method
(*Minecraft_init)(minecraft); (*Minecraft_init_non_virtual)(minecraft);
unsigned char *options = minecraft + Minecraft_options_property_offset; Options *options = &minecraft->options;
// Enable Crosshair In Touch GUI // Enable Crosshair In Touch GUI
*(options + Options_split_controls_property_offset) = 1; options->split_controls = 1;
// Render Distance // Render Distance
*(int32_t *) (options + Options_render_distance_property_offset) = render_distance; options->render_distance = render_distance;
} }
// Smooth Lighting // Smooth Lighting
static void TileRenderer_tesselateBlockInWorld_injection(unsigned char *tile_renderer, unsigned char *tile, int32_t x, int32_t y, int32_t z) { static void TileRenderer_tesselateBlockInWorld_injection(TileRenderer *tile_renderer, Tile *tile, int32_t x, int32_t y, int32_t z) {
// Set Variable // Set Variable
*Minecraft_useAmbientOcclusion = *(stored_options + Options_ambient_occlusion_property_offset); *Minecraft_useAmbientOcclusion = stored_options->ambient_occlusion;
// Call Original Method // Call Original Method
(*TileRenderer_tesselateBlockInWorld)(tile_renderer, tile, x, y, z); (*TileRenderer_tesselateBlockInWorld)(tile_renderer, tile, x, y, z);
@ -93,16 +93,16 @@ void init_options() {
// Set Options // Set Options
overwrite_calls((void *) Options_initDefaultValue, (void *) Options_initDefaultValue_injection); overwrite_calls((void *) Options_initDefaultValue, (void *) Options_initDefaultValue_injection);
overwrite_calls((void *) Minecraft_init, (void *) Minecraft_init_injection); overwrite_calls((void *) Minecraft_init_non_virtual, (void *) Minecraft_init_injection);
// Change Username // Change Username
const char *username = get_username(); const char *username = get_username();
DEBUG("Setting Username: %s", username); DEBUG("Setting Username: %s", username);
if (strcmp(*default_username, "StevePi") != 0) { if (strcmp(*Strings_default_username, "StevePi") != 0) {
ERR("Default Username Is Invalid"); ERR("Default Username Is Invalid");
} }
safe_username = to_cp437(username); safe_username = to_cp437(username);
patch_address((void *) default_username, (void *) safe_username); patch_address((void *) Strings_default_username, (void *) safe_username);
// Disable Autojump By Default // Disable Autojump By Default
if (feature_has("Disable Autojump By Default", server_disabled)) { if (feature_has("Disable Autojump By Default", server_disabled)) {

View File

@ -13,9 +13,9 @@
// Fix Initial Option Button Rendering // Fix Initial Option Button Rendering
// The calling function doesn't exist in MCPE v0.6.1, so its name is unknown. // The calling function doesn't exist in MCPE v0.6.1, so its name is unknown.
static unsigned char *OptionsPane_unknown_toggle_creating_function_OptionButton_injection(unsigned char *option_button, unsigned char *option) { static OptionButton *OptionsPane_unknown_toggle_creating_function_OptionButton_injection(OptionButton *option_button, Options_Option *option) {
// Call Original Method // Call Original Method
unsigned char *ret = (*OptionButton)(option_button, option); OptionButton *ret = (*OptionButton_constructor)(option_button, option);
// Setup Image // Setup Image
(*OptionButton_updateImage)(option_button, stored_options); (*OptionButton_updateImage)(option_button, stored_options);
@ -26,25 +26,25 @@ static unsigned char *OptionsPane_unknown_toggle_creating_function_OptionButton_
// Actually Save options.txt // Actually Save options.txt
// Hook Last Options::addOptionToSaveOutput Call // Hook Last Options::addOptionToSaveOutput Call
static void Options_save_Options_addOptionToSaveOutput_injection(unsigned char *options, std::vector<std::string> &data, std::string option, int32_t value) { static void Options_save_Options_addOptionToSaveOutput_injection(Options *options, std::vector<std::string> *data, std::string option, int32_t value) {
// Call Original Method // Call Original Method
(*Options_addOptionToSaveOutput)(options, data, option, value); (*Options_addOptionToSaveOutput)(options, data, option, value);
// Save Fancy Graphics // Save Fancy Graphics
(*Options_addOptionToSaveOutput)(options, data, "gfx_fancygraphics", *(options + Options_fancy_graphics_property_offset)); (*Options_addOptionToSaveOutput)(options, data, "gfx_fancygraphics", options->fancy_graphics);
// Save 3D Anaglyph // Save 3D Anaglyph
(*Options_addOptionToSaveOutput)(options, data, "gfx_anaglyph", *(options + Options_3d_anaglyph_property_offset)); (*Options_addOptionToSaveOutput)(options, data, "gfx_anaglyph", options->anaglyph_3d);
// Save File // Save File
unsigned char *options_file = options + Options_options_file_property_offset; OptionsFile *options_file = &options->options_file;
(*OptionsFile_save)(options_file, data); (*OptionsFile_save)(options_file, data);
} }
// MCPI's OptionsFile::getOptionStrings is broken, this is the version in v0.7.0 // MCPI's OptionsFile::getOptionStrings is broken, this is the version in v0.7.0
static std::vector<std::string> OptionsFile_getOptionStrings_injection(unsigned char *options_file) { static std::vector<std::string> OptionsFile_getOptionStrings_injection(OptionsFile *options_file) {
// Get options.txt Path // Get options.txt Path
std::string path = *(std::string *) (options_file + OptionsFile_options_txt_path_property_offset); std::string path = options_file->options_txt_path;
// Parse // Parse
std::vector<std::string> ret; std::vector<std::string> ret;
FILE *stream = fopen(path.c_str(), "r"); FILE *stream = fopen(path.c_str(), "r");
@ -94,8 +94,9 @@ static char *get_new_options_txt_path() {
#endif #endif
// Modify Option Toggles // Modify Option Toggles
static void OptionsPane_unknown_toggle_creating_function_injection(unsigned char *options_pane, uint32_t group_id, std::string const& name, unsigned char *option) { static void OptionsPane_unknown_toggle_creating_function_injection(OptionsPane *options_pane, uint32_t group_id, std::string *name_ptr, Options_Option *option) {
// Modify // Modify
std::string name = *name_ptr;
std::string new_name = name; std::string new_name = name;
if (name == "Fancy Graphics") { if (name == "Fancy Graphics") {
option = Options_Option_GRAPHICS; option = Options_Option_GRAPHICS;
@ -119,19 +120,20 @@ static void OptionsPane_unknown_toggle_creating_function_injection(unsigned char
} }
// Call Original Method // Call Original Method
(*OptionsPane_unknown_toggle_creating_function)(options_pane, group_id, new_name, option); (*OptionsPane_unknown_toggle_creating_function)(options_pane, group_id, &new_name, option);
// Add 3D Anaglyph // Add 3D Anaglyph
if (option == Options_Option_GRAPHICS) { if (option == Options_Option_GRAPHICS) {
(*OptionsPane_unknown_toggle_creating_function)(options_pane, group_id, "3D Anaglyph", Options_Option_ANAGLYPH); std::string cpp_string = "3D Anaglyph";
(*OptionsPane_unknown_toggle_creating_function)(options_pane, group_id, &cpp_string, Options_Option_ANAGLYPH);
} }
} }
// Add Missing Options To Options::getBooleanValue // Add Missing Options To Options::getBooleanValue
static bool Options_getBooleanValue_injection(unsigned char *options, unsigned char *option) { static bool Options_getBooleanValue_injection(Options *options, Options_Option *option) {
// Check // Check
if (option == Options_Option_GRAPHICS) { if (option == Options_Option_GRAPHICS) {
return *(options + Options_fancy_graphics_property_offset); return options->fancy_graphics;
} else { } else {
// Call Original Method // Call Original Method
return (*Options_getBooleanValue)(options, option); return (*Options_getBooleanValue)(options, option);
@ -167,9 +169,9 @@ void _init_options_cpp() {
// Actually Save options.txt // Actually Save options.txt
overwrite_call((void *) 0x197fc, (void *) Options_save_Options_addOptionToSaveOutput_injection); overwrite_call((void *) 0x197fc, (void *) Options_save_Options_addOptionToSaveOutput_injection);
// Fix options.txt Path // Fix options.txt Path
patch_address((void *) options_txt_path, (void *) get_new_options_txt_path()); patch_address((void *) Strings_options_txt_path, (void *) get_new_options_txt_path());
// When Loading, options.txt Should Be Opened In Read Mode // When Loading, options.txt Should Be Opened In Read Mode
patch_address((void *) options_txt_fopen_mode_when_loading, (void *) "r"); patch_address((void *) Strings_options_txt_fopen_mode_when_loading, (void *) "r");
// Fix OptionsFile::getOptionStrings // Fix OptionsFile::getOptionStrings
overwrite_calls((void *) OptionsFile_getOptionStrings, (void *) OptionsFile_getOptionStrings_injection); overwrite_calls((void *) OptionsFile_getOptionStrings, (void *) OptionsFile_getOptionStrings_injection);
@ -189,13 +191,14 @@ void _init_options_cpp() {
{ {
// Replace String // Replace String
static const char *new_feedback_vibration_options_txt_name = "gfx_ao"; static const char *new_feedback_vibration_options_txt_name = "gfx_ao";
patch_address((void *) feedback_vibration_options_txt_name_1, (void *) &new_feedback_vibration_options_txt_name); patch_address((void *) Strings_feedback_vibration_options_txt_name_1, (void *) &new_feedback_vibration_options_txt_name);
patch_address((void *) feedback_vibration_options_txt_name_2, (void *) &new_feedback_vibration_options_txt_name); patch_address((void *) Strings_feedback_vibration_options_txt_name_2, (void *) &new_feedback_vibration_options_txt_name);
// Loading // Loading
unsigned char gfx_ao_loading_patch[4] = {(unsigned char) Options_ambient_occlusion_property_offset, 0x10, 0x84, 0xe2}; // "add r1, r4, #OFFSET" unsigned char offset = (unsigned char) offsetof(Options, ambient_occlusion);
unsigned char gfx_ao_loading_patch[4] = {offset, 0x10, 0x84, 0xe2}; // "add r1, r4, #OFFSET"
patch((void *) 0x193b8, gfx_ao_loading_patch); patch((void *) 0x193b8, gfx_ao_loading_patch);
// Saving // Saving
unsigned char gfx_ao_saving_patch[4] = {(unsigned char) Options_ambient_occlusion_property_offset, 0x30, 0xd4, 0xe5}; // "ldrb r3, [r4, #OFFSET]" unsigned char gfx_ao_saving_patch[4] = {offset, 0x30, 0xd4, 0xe5}; // "ldrb r3, [r4, #OFFSET]"
patch((void *) 0x197f8, gfx_ao_saving_patch); patch((void *) 0x197f8, gfx_ao_saving_patch);
} }
@ -203,9 +206,10 @@ void _init_options_cpp() {
{ {
// Replace String // Replace String
static const char *new_gfx_lowquality_options_txt_name = "gfx_anaglyph"; static const char *new_gfx_lowquality_options_txt_name = "gfx_anaglyph";
patch_address((void *) gfx_lowquality_options_txt_name, (void *) &new_gfx_lowquality_options_txt_name); patch_address((void *) Strings_gfx_lowquality_options_txt_name, (void *) &new_gfx_lowquality_options_txt_name);
// Loading // Loading
unsigned char gfx_anaglyph_loading_patch[4] = {(unsigned char) Options_3d_anaglyph_property_offset, 0x10, 0x84, 0xe2}; // "add r1, r4, #OFFSET" unsigned char offset = (unsigned char) offsetof(Options, anaglyph_3d);
unsigned char gfx_anaglyph_loading_patch[4] = {offset, 0x10, 0x84, 0xe2}; // "add r1, r4, #OFFSET"
patch((void *) 0x19400, gfx_anaglyph_loading_patch); patch((void *) 0x19400, gfx_anaglyph_loading_patch);
// Disable Loading Side Effects // Disable Loading Side Effects
patch((void *) 0x19414, nop_patch); patch((void *) 0x19414, nop_patch);

View File

@ -15,18 +15,18 @@ static int32_t sdl_key_to_minecraft_key_injection(int32_t sdl_key) {
return 8; return 8;
} else { } else {
// Call Original Method // Call Original Method
return (*sdl_key_to_minecraft_key)(sdl_key); return (*Common_sdl_key_to_minecraft_key)(sdl_key);
} }
} }
// Open Sign Screen // Open Sign Screen
static void LocalPlayer_openTextEdit_injection(unsigned char *local_player, unsigned char *sign) { static void LocalPlayer_openTextEdit_injection(LocalPlayer *local_player, TileEntity *sign) {
if (*(int32_t *) (sign + TileEntity_id_property_offset) == 4) { if (sign->id == 4) {
unsigned char *minecraft = *(unsigned char **) (local_player + LocalPlayer_minecraft_property_offset); Minecraft *minecraft = local_player->minecraft;
unsigned char *screen = (unsigned char *) ::operator new(TEXT_EDIT_SCREEN_SIZE); TextEditScreen *screen = alloc_TextEditScreen();
ALLOC_CHECK(screen); ALLOC_CHECK(screen);
screen = (*TextEditScreen)(screen, sign); screen = (*TextEditScreen_constructor)(screen, (SignTileEntity *) sign);
(*Minecraft_setScreen)(minecraft, screen); (*Minecraft_setScreen)(minecraft, (Screen *) screen);
} }
} }
@ -35,20 +35,19 @@ std::vector<char> input;
void sign_key_press(char key) { void sign_key_press(char key) {
input.push_back(key); input.push_back(key);
} }
static void clear_input(__attribute__((unused)) unsigned char *minecraft) { static void clear_input(__attribute__((unused)) Minecraft *minecraft) {
input.clear(); input.clear();
} }
// Handle Text Input // Handle Text Input
static void TextEditScreen_updateEvents_injection(unsigned char *screen) { static void TextEditScreen_updateEvents_injection(TextEditScreen *screen) {
// Call Original Method // Call Original Method
(*Screen_updateEvents)(screen); (*TextEditScreen_updateEvents_non_virtual)(screen);
if (!*(bool *)(screen + Screen_passthrough_input_property_offset)) { if (!screen->passthrough_input) {
unsigned char *vtable = *(unsigned char **) screen;
for (char key : input) { for (char key : input) {
// Handle Normal Key // Handle Normal Key
(*(Screen_keyboardNewChar_t *) (vtable + Screen_keyboardNewChar_vtable_offset))(screen, key); screen->vtable->keyboardNewChar(screen, key);
} }
} }
clear_input(NULL); clear_input(NULL);
@ -58,7 +57,7 @@ static void TextEditScreen_updateEvents_injection(unsigned char *screen) {
void init_sign() { void init_sign() {
if (feature_has("Fix Sign Placement", server_disabled)) { if (feature_has("Fix Sign Placement", server_disabled)) {
// Handle Backspace // Handle Backspace
overwrite_calls((void *) sdl_key_to_minecraft_key, (void *) sdl_key_to_minecraft_key_injection); overwrite_calls((void *) Common_sdl_key_to_minecraft_key, (void *) sdl_key_to_minecraft_key_injection);
// Fix Signs // Fix Signs
patch_address(LocalPlayer_openTextEdit_vtable_addr, (void *) LocalPlayer_openTextEdit_injection); patch_address(LocalPlayer_openTextEdit_vtable_addr, (void *) LocalPlayer_openTextEdit_injection);
patch_address(TextEditScreen_updateEvents_vtable_addr, (void *) TextEditScreen_updateEvents_injection); patch_address(TextEditScreen_updateEvents_vtable_addr, (void *) TextEditScreen_updateEvents_injection);

View File

@ -27,7 +27,7 @@ static std::vector<pending_skin> &get_pending_skins() {
return pending_skins; return pending_skins;
} }
static pthread_mutex_t pending_skins_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t pending_skins_lock = PTHREAD_MUTEX_INITIALIZER;
static void load_pending_skins(__attribute__((unused)) unsigned char *minecraft) { static void load_pending_skins(__attribute__((unused)) Minecraft *minecraft) {
// Lock // Lock
pthread_mutex_lock(&pending_skins_lock); pthread_mutex_lock(&pending_skins_lock);
@ -114,14 +114,14 @@ static void *loader_thread(void *user_data) {
} }
// Intercept Texture Creation // Intercept Texture Creation
static int32_t Textures_assignTexture_injection(unsigned char *textures, std::string const& name, unsigned char *data) { static int32_t Textures_assignTexture_injection(Textures *textures, std::string *name, unsigned char *data) {
// Call Original Method // Call Original Method
int32_t id = (*Textures_assignTexture)(textures, name, data); int32_t id = (*Textures_assignTexture)(textures, name, data);
// Load Skin // Load Skin
if (starts_with(name.c_str(), "$")) { if (starts_with(name->c_str(), "$")) {
loader_data *user_data = new loader_data; loader_data *user_data = new loader_data;
user_data->name = name.substr(1); user_data->name = name->substr(1);
DEBUG("Loading Skin: %s", user_data->name.c_str()); DEBUG("Loading Skin: %s", user_data->name.c_str());
user_data->texture_id = id; user_data->texture_id = id;
// Start Thread // Start Thread

View File

@ -52,9 +52,9 @@ static void Player_username_assign_injection(std::string *target, std::string *u
*target = *username; *target = *username;
// Get Player // Get Player
unsigned char *player = ((unsigned char *) target) - Player_username_property_offset; Player *player = (Player *) (((unsigned char *) target) - offsetof(Player, username));
// Get Texture // Get Texture
std::string *texture = (std::string *) (player + Mob_texture_property_offset); std::string *texture = &player->texture;
// Set Texture // Set Texture
*texture = '$' + base64_encode(*username); *texture = '$' + base64_encode(*username);
@ -65,16 +65,16 @@ static void Player_username_assign_injection_2(std::string *target, const char *
} }
// Change Texture For HUD // Change Texture For HUD
static int32_t Textures_loadAndBindTexture_injection(unsigned char *textures, __attribute__((unused)) std::string const& name) { static int32_t Textures_loadAndBindTexture_injection(Textures *textures, __attribute__((unused)) std::string const& name) {
// Change Texture // Change Texture
static std::string new_texture; static std::string new_texture;
if (new_texture.length() == 0) { if (new_texture.length() == 0) {
std::string username = base64_encode(*default_username); std::string username = base64_encode(*Strings_default_username);
new_texture = '$' + username; new_texture = '$' + username;
} }
// Call Original Method // Call Original Method
return (*Textures_loadAndBindTexture)(textures, new_texture); return (*Textures_loadAndBindTexture)(textures, &new_texture);
} }
// Init // Init

View File

@ -74,7 +74,7 @@ static void SoundEngine_play_injection(__attribute__((unused)) unsigned char *so
} }
// Refresh Data // Refresh Data
static void SoundEngine_update_injection(unsigned char *sound_engine, unsigned char *listener_mob, __attribute__((unused)) float listener_angle) { static void SoundEngine_update_injection(SoundEngine *sound_engine, Mob *listener_mob, __attribute__((unused)) float listener_angle) {
// Variables // Variables
static float volume = 0; static float volume = 0;
static float x = 0; static float x = 0;
@ -83,19 +83,19 @@ static void SoundEngine_update_injection(unsigned char *sound_engine, unsigned c
static float yaw = 0; static float yaw = 0;
// SoundEngine Properties // SoundEngine Properties
unsigned char *options = *(unsigned char **) (sound_engine + SoundEngine_options_property_offset); Options *options = sound_engine->options;
// Volume // Volume
int32_t sound_enabled = *(int32_t *) (options + Options_sound_property_offset); int32_t sound_enabled = options->sound;
volume = sound_enabled ? 1 : 0; volume = sound_enabled ? 1 : 0;
// Position And Rotation // Position And Rotation
if (listener_mob != NULL) { if (listener_mob != NULL) {
// Values // Values
x = *(float *) (listener_mob + Entity_x_property_offset); x = listener_mob->x;
y = *(float *) (listener_mob + Entity_y_property_offset); y = listener_mob->y;
z = *(float *) (listener_mob + Entity_z_property_offset); z = listener_mob->z;
yaw = *(float *) (listener_mob + Entity_yaw_property_offset); yaw = listener_mob->yaw;
} }
// Log // Log
@ -104,7 +104,7 @@ static void SoundEngine_update_injection(unsigned char *sound_engine, unsigned c
// Resolve All Sounds On Init // Resolve All Sounds On Init
// SoundEngine::init Is Called After The Audio Engine Has Been Loaded // SoundEngine::init Is Called After The Audio Engine Has Been Loaded
static void SoundEngine_init_injection(unsigned char *sound_engine, unsigned char *minecraft, unsigned char *options) { static void SoundEngine_init_injection(SoundEngine *sound_engine, Minecraft *minecraft, Options *options) {
// Call Original Method // Call Original Method
(*SoundEngine_init)(sound_engine, minecraft, options); (*SoundEngine_init)(sound_engine, minecraft, options);

View File

@ -15,9 +15,9 @@
#include "stb_image.h" #include "stb_image.h"
// Animated Water // Animated Water
static void Minecraft_tick_injection(unsigned char *minecraft) { static void Minecraft_tick_injection(Minecraft *minecraft) {
// Tick Dynamic Textures // Tick Dynamic Textures
unsigned char *textures = *(unsigned char **) (minecraft + Minecraft_textures_property_offset); Textures *textures = minecraft->textures;
if (textures != NULL) { if (textures != NULL) {
(*Textures_tick)(textures, true); (*Textures_tick)(textures, true);
} }
@ -169,13 +169,23 @@ static void Textures_tick_glTexSubImage2D_injection(GLenum target, GLint level,
} }
// Load Textures // Load Textures
static Texture AppPlatform_linux_loadTexture_injection(__attribute__((unused)) unsigned char *app_platform, std::string const& path, bool b) { static Texture AppPlatform_linux_loadTexture_injection(__attribute__((unused)) AppPlatform_linux *app_platform, std::string *path, bool b) {
Texture out; Texture out;
std::string real_path = path; std::string real_path = *path;
if (b) { if (b) {
real_path = "data/images/" + real_path; real_path = "data/images/" + real_path;
} }
// Empty Texture
out.width = 0;
out.height = 0;
out.data = NULL;
out.field3_0xc = 0;
out.field4_0x10 = true;
out.field5_0x11 = false;
out.field6_0x14 = 0;
out.field7_0x18 = -1;
// Read Image // Read Image
int width = 0, height = 0, channels = 0; int width = 0, height = 0, channels = 0;
stbi_uc *img = stbi_load(real_path.c_str(), &width, &height, &channels, STBI_rgb_alpha); stbi_uc *img = stbi_load(real_path.c_str(), &width, &height, &channels, STBI_rgb_alpha);
@ -211,5 +221,5 @@ void init_textures() {
overwrite_call((void *) 0x53274, (void *) Textures_tick_glTexSubImage2D_injection); overwrite_call((void *) 0x53274, (void *) Textures_tick_glTexSubImage2D_injection);
// Load Textures // Load Textures
overwrite((void *) AppPlatform_linux_loadTexture, (void *) AppPlatform_linux_loadTexture_injection); overwrite((void *) AppPlatform_linux_loadTexture_non_virtual, (void *) AppPlatform_linux_loadTexture_injection);
} }

View File

@ -6,39 +6,40 @@
#include <mods/compat/compat.h> #include <mods/compat/compat.h>
// Improved Title Screen Background // Improved Title Screen Background
static void StartMenuScreen_render_Screen_renderBackground_injection(unsigned char *screen) { static void StartMenuScreen_render_Screen_renderBackground_injection(StartMenuScreen *screen) {
// Draw // Draw
unsigned char *minecraft = *(unsigned char **) (screen + Screen_minecraft_property_offset); Minecraft *minecraft = screen->minecraft;
unsigned char *textures = *(unsigned char **) (minecraft + Minecraft_textures_property_offset); Textures *textures = minecraft->textures;
(*Textures_loadAndBindTexture)(textures, "gui/titleBG.png"); std::string texture = "gui/titleBG.png";
(*GuiComponent_blit)(screen, 0, 0, 0, 0, *(int32_t *) (screen + Screen_width_property_offset), *(int32_t *) (screen + Screen_height_property_offset), 0x100, 0x100); (*Textures_loadAndBindTexture)(textures, &texture);
(*StartMenuScreen_blit)(screen, 0, 0, 0, 0, screen->width, screen->height, 0x100, 0x100);
} }
// Add Buttons Back To Classic Start Screen // Add Buttons Back To Classic Start Screen
static void StartMenuScreen_init_injection(unsigned char *screen) { static void StartMenuScreen_init_injection(StartMenuScreen *screen) {
// Call Original Method // Call Original Method
(*StartMenuScreen_init)(screen); (*StartMenuScreen_init_non_virtual)(screen);
// Add Button // Add Button
std::vector<unsigned char *> *rendered_buttons = (std::vector<unsigned char *> *) (screen + Screen_rendered_buttons_property_offset); std::vector<Button *> *rendered_buttons = &screen->rendered_buttons;
std::vector<unsigned char *> *selectable_buttons = (std::vector<unsigned char *> *) (screen + Screen_selectable_buttons_property_offset); std::vector<Button *> *selectable_buttons = &screen->selectable_buttons;
unsigned char *options_button = screen + StartMenuScreen_options_button_property_offset; Button *options_button = &screen->options_button;
rendered_buttons->push_back(options_button); rendered_buttons->push_back(options_button);
selectable_buttons->push_back(options_button); selectable_buttons->push_back(options_button);
unsigned char *create_button = screen + StartMenuScreen_create_button_property_offset; // Repurpose Unused "Create" Button As Quit Button Button *create_button = &screen->create_button; // Repurpose Unused "Create" Button As Quit Button
rendered_buttons->push_back(create_button); rendered_buttons->push_back(create_button);
selectable_buttons->push_back(create_button); selectable_buttons->push_back(create_button);
} }
// Add Functionality To Quit Button // Add Functionality To Quit Button
static void StartMenuScreen_buttonClicked_injection(unsigned char *screen, unsigned char *button) { static void StartMenuScreen_buttonClicked_injection(StartMenuScreen *screen, Button *button) {
unsigned char *quit_button = screen + StartMenuScreen_create_button_property_offset; Button *quit_button = &screen->create_button;
if (button == quit_button) { if (button == quit_button) {
// Quit // Quit
compat_request_exit(); compat_request_exit();
} else { } else {
// Call Original Method // Call Original Method
(*StartMenuScreen_buttonClicked)(screen, button); (*StartMenuScreen_buttonClicked_non_virtual)(screen, button);
} }
} }
@ -78,7 +79,7 @@ void init_title_screen() {
} }
// Rename "Create" Button To "Quit" // Rename "Create" Button To "Quit"
patch_address((void *) classic_create_button_text, (void *) "Quit"); patch_address((void *) Strings_classic_create_button_text, (void *) "Quit");
// Add Functionality To Quit Button // Add Functionality To Quit Button
patch_address(StartMenuScreen_buttonClicked_vtable_addr, (void *) StartMenuScreen_buttonClicked_injection); patch_address(StartMenuScreen_buttonClicked_vtable_addr, (void *) StartMenuScreen_buttonClicked_injection);

View File

@ -6,7 +6,7 @@
#include <symbols/minecraft.h> #include <symbols/minecraft.h>
// Enable Touch GUI // Enable Touch GUI
static int32_t Minecraft_isTouchscreen_injection(__attribute__((unused)) unsigned char *minecraft) { static int32_t Minecraft_isTouchscreen_injection(__attribute__((unused)) Minecraft *minecraft) {
return 1; return 1;
} }
@ -16,23 +16,23 @@ static unsigned char *operator_new_IngameBlockSelectionScreen_injection(__attrib
} }
// Improved Button Hover Behavior // Improved Button Hover Behavior
static int32_t Button_hovered_injection(__attribute__((unused)) unsigned char *button, __attribute__((unused)) unsigned char *minecraft, __attribute__((unused)) int32_t click_x, __attribute__((unused)) int32_t click_y) { static int32_t Button_hovered_injection(__attribute__((unused)) Button *button, __attribute__((unused)) Minecraft *minecraft, __attribute__((unused)) int32_t click_x, __attribute__((unused)) int32_t click_y) {
// Get Mouse Position // Get Mouse Position
int32_t x = (*Mouse_getX)() * (*InvGuiScale); int32_t x = (*Mouse_getX)() * (*Gui_InvGuiScale);
int32_t y = (*Mouse_getY)() * (*InvGuiScale); int32_t y = (*Mouse_getY)() * (*Gui_InvGuiScale);
// Get Button Position // Get Button Position
int32_t button_x1 = *(int32_t *) (button + Button_x_property_offset); int32_t button_x1 = button->x;
int32_t button_y1 = *(int32_t *) (button + Button_y_property_offset); int32_t button_y1 = button->y;
int32_t button_x2 = button_x1 + (*(int32_t *) (button + Button_width_property_offset)); int32_t button_x2 = button_x1 + button->width;
int32_t button_y2 = button_y1 + (*(int32_t *) (button + Button_height_property_offset)); int32_t button_y2 = button_y1 + button->height;
// Check // Check
return x >= button_x1 && x <= button_x2 && y >= button_y1 && y <= button_y2; return x >= button_x1 && x <= button_x2 && y >= button_y1 && y <= button_y2;
} }
static void LargeImageButton_render_GuiComponent_drawCenteredString_injection(unsigned char *component, unsigned char *font, std::string const& text, int32_t x, int32_t y, int32_t color) { static void LargeImageButton_render_GuiComponent_drawCenteredString_injection(GuiComponent *component, Font *font, std::string *text, int32_t x, int32_t y, int32_t color) {
// Change Color On Hover // Change Color On Hover
if (color == 0xe0e0e0 && Button_hovered_injection(component, NULL, 0, 0)) { if (color == 0xe0e0e0 && Button_hovered_injection((Button *) component, NULL, 0, 0)) {
color = 0xffffa0; color = 0xffffa0;
} }
@ -55,10 +55,10 @@ void init_touch() {
// Force Touch Inventory // Force Touch Inventory
if (feature_has("Force Touch GUI Inventory", server_disabled)) { if (feature_has("Force Touch GUI Inventory", server_disabled)) {
overwrite_call((void *) 0x2943c, (void *) operator_new_IngameBlockSelectionScreen_injection); overwrite_call((void *) 0x2943c, (void *) operator_new_IngameBlockSelectionScreen_injection);
overwrite_call((void *) 0x29444, (void *) Touch_IngameBlockSelectionScreen); overwrite_call((void *) 0x29444, (void *) Touch_IngameBlockSelectionScreen_constructor);
// Make "Craft" And "Armor" Buttons Use Classic GUI Style (Button And TButton Have The Same Size) // Make "Craft" And "Armor" Buttons Use Classic GUI Style (Button And TButton Have The Same Size)
overwrite_call((void *) 0x3b060, (void *) Button); overwrite_call((void *) 0x3b060, (void *) Button_constructor);
overwrite_call((void *) 0x3b08c, (void *) Button); overwrite_call((void *) 0x3b08c, (void *) Button_constructor);
} }
// Force Touch Button Behavior // Force Touch Button Behavior

View File

@ -9,7 +9,7 @@ char *version_get() {
static char *version = NULL; static char *version = NULL;
// Load // Load
if (version == NULL) { if (version == NULL) {
safe_asprintf(&version, "%s / Reborn v%s", *minecraft_pi_version, reborn_get_version()); safe_asprintf(&version, "%s / Reborn v%s", *Strings_minecraft_pi_version, reborn_get_version());
} }
// Return // Return
return version; return version;
@ -30,7 +30,7 @@ void init_version() {
// Touch GUI // Touch GUI
overwrite((void *) Common_getGameVersionString, (void *) Common_getGameVersionString_injection); overwrite((void *) Common_getGameVersionString, (void *) Common_getGameVersionString_injection);
// Normal GUI // Normal GUI
patch_address((void *) minecraft_pi_version, version_get()); patch_address((void *) Strings_minecraft_pi_version, version_get());
// Log // Log
INFO("Starting Minecraft: Pi Edition (%s)", version_get()); INFO("Starting Minecraft: Pi Edition (%s)", version_get());

View File

@ -1,16 +1,175 @@
project(symbols) project(symbols)
add_library(symbols INTERFACE) # Definition Files
set(SRC
src/LeafTile.def
src/ServerPlayer.def
src/Tile.def
src/Material.def
src/RakNetInstance.def
src/LiquidTile.def
src/LoginPacket.def
src/ChestTileEntity.def
src/InBedScreen.def
src/LevelSource.def
src/TallGrass.def
src/Player.def
src/ImageButton.def
src/Strings.def
src/ExternalFileLevelStorageSource.def
src/TileEntity.def
src/ItemRenderer.def
src/ModelPart.def
src/Biome.def
src/SimpleChooseLevelScreen.def
src/PauseScreen.def
src/Tesselator.def
src/AABB.def
src/AppPlatform.def
src/Minecraft.def
src/OptionsFile.def
src/EntityRenderer.def
src/RakNet_RakString_SharedString.def
src/ChunkSource.def
src/Vec3.def
src/NetEventCallback.def
src/PathfinderMob.def
src/Level.def
src/RakNet_RakString.def
src/StemTile.def
src/LevelRenderer.def
src/FillingContainer.def
src/HumanoidModel.def
src/TripodCameraRenderer.def
src/FurnaceScreen.def
src/HitResult.def
src/Container.def
src/PerfRenderer.def
src/ParticleEngine.def
src/PlayerRenderer.def
src/GameMode.def
src/Font.def
src/RemotePlayer.def
src/EntityRenderDispatcher.def
src/Texture.def
src/MobRenderer.def
src/LargeFeature.def
src/ContainerMenu.def
src/Textures.def
src/FurnaceTileEntity.def
src/TileRenderer.def
src/GrassTile.def
src/WorkbenchScreen.def
src/Packet.def
src/RandomLevelSource.def
src/SelectWorldScreen.def
src/AuxDataTileItem.def
src/OptionButton.def
src/Touch_IngameBlockSelectionScreen.def
src/OptionsPane.def
src/HeavyTile.def
src/Options.def
src/AppPlatform_linux.def
src/StartGamePacket.def
src/IBuildInput.def
src/ItemInstance.def
src/SoundEngine.def
src/GuiComponent.def
src/NinecraftApp.def
src/Mob.def
src/MouseBuildInput.def
src/FurnaceRecipes.def
src/Recipes.def
src/Button.def
src/ChatPacket.def
src/LevelData.def
src/ServerSideNetworkHandler.def
src/LargeCaveFeature.def
src/Screen.def
src/CreatorMode.def
src/HumanoidMobRenderer.def
src/OptionsScreen.def
src/Gui.def
src/Recipes_Type.def
src/Inventory.def
src/Common.def
src/CommandServer.def
src/RakNet_SystemAddress.def
src/LevelSettings.def
src/ServerLevel.def
src/Item.def
src/extra.h
src/Entity.def
src/RakNet_RakNetGUID.def
src/RakNet_RakPeer.def
src/Config.def
src/ConnectedClient.def
src/Mouse.def
src/GameRenderer.def
src/SurvivalMode.def
src/AppPlatform_readAssetFile_return_value.def
src/TextEditScreen.def
src/StartMenuScreen.def
src/ProgressScreen.def
src/LocalPlayer.def
src/Touch_SelectWorldScreen.def
src/TileItem.def
src/Tile_SoundType.def
src/Options_Option.def
src/LevelStorageSource.def
src/SignTileEntity.def
)
# Resolve Definition Files
set(RESOLVED_SRC "")
foreach(FILE IN LISTS SRC)
list(APPEND RESOLVED_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}")
endforeach()
# Directories
function(set_and_mkdir name dir)
set("${name}" "${dir}" PARENT_SCOPE)
file(MAKE_DIRECTORY "${dir}")
endfunction()
set_and_mkdir(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
set_and_mkdir(INCLUDE_OUTPUT_DIR "${GENERATED_DIR}/include")
set_and_mkdir(HEADER_OUTPUT_DIR "${INCLUDE_OUTPUT_DIR}/symbols")
set_and_mkdir(SRC_OUTPUT_DIR "${GENERATED_DIR}/src")
# Files
set(HEADER_OUTPUT_FILE "${HEADER_OUTPUT_DIR}/minecraft.h")
set(SRC_OUTPUT_FILE "${SRC_OUTPUT_DIR}/minecraft.cpp")
# Generate
add_custom_command(
OUTPUT "${SRC_OUTPUT_FILE}" "${HEADER_OUTPUT_FILE}"
DEPENDS ${RESOLVED_SRC}
COMMAND npm start --silent -- "${SRC_OUTPUT_FILE}" "${HEADER_OUTPUT_FILE}" ${RESOLVED_SRC}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../dependencies/symbol-processor/src"
VERBATIM
)
# Build
add_library(symbols SHARED "${SRC_OUTPUT_FILE}" "${HEADER_OUTPUT_FILE}")
# Show In IDE
add_custom_target(symbols-src
DEPENDS "${SRC_OUTPUT_FILE}" "${HEADER_OUTPUT_FILE}"
SOURCES ${RESOLVED_SRC}
)
# Include Directory
target_include_directories( target_include_directories(
symbols symbols
INTERFACE PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" "$<BUILD_INTERFACE:${INCLUDE_OUTPUT_DIR}>"
"$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/symbols>" "$<INSTALL_INTERFACE:${MCPI_SDK_INCLUDE_DIR}/symbols>"
) )
# Disable C++11 String ABI # Disable C++11 String ABI
target_compile_definitions(symbols INTERFACE -D_GLIBCXX_USE_CXX11_ABI=0) target_compile_definitions(symbols PUBLIC -D_GLIBCXX_USE_CXX11_ABI=0)
# Install
install(TARGETS symbols DESTINATION "${MCPI_LIB_DIR}")
# SDK # SDK
install(TARGETS symbols EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}") install(TARGETS symbols EXPORT sdk DESTINATION "${MCPI_SDK_LIB_DIR}")
install(DIRECTORY "include/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/symbols") install(DIRECTORY "${INCLUDE_OUTPUT_DIR}/" DESTINATION "${MCPI_SDK_INCLUDE_DIR}/symbols")

File diff suppressed because it is too large Load Diff

8
symbols/src/AABB.def Normal file
View File

@ -0,0 +1,8 @@
size 0x18;
property float x1 = 0x0;
property float y1 = 0x4;
property float z1 = 0x8;
property float x2 = 0xc;
property float y2 = 0x10;
property float z2 = 0x14;

View File

@ -0,0 +1,5 @@
vtable 0x1020d8;
virtual-method void saveScreenshot(std::string *path, int width, int height) = 0x8;
virtual-method AppPlatform_readAssetFile_return_value readAssetFile(std::string *path) = 0x34;
virtual-method Texture loadTexture(std::string *path, bool b) = 0xc;

View File

@ -0,0 +1,3 @@
extends AppPlatform;
vtable 0x102158;

View File

@ -0,0 +1,4 @@
size 0x8;
property char *data = 0x0;
property int length = 0x4;

View File

@ -0,0 +1,7 @@
extends Item;
vtable 0x114a58;
size 0x2c;
property Tile *icon_tile = 0x28;

2
symbols/src/Biome.def Normal file
View File

@ -0,0 +1,2 @@
property int color = 0x2c;
property int leaf_color = 0x34;

10
symbols/src/Button.def Normal file
View File

@ -0,0 +1,10 @@
extends GuiComponent;
constructor (int param_1, std::string *text) = 0x1bc54;
method int hovered(Minecraft *minecraft, int click_x, int click_y) = 0x1be2c;
property int width = 0x14;
property int height = 0x18;
property int x = 0xc;
property int y = 0x10;

View File

@ -0,0 +1,3 @@
extends Packet;
property char *message = 0xc;

View File

@ -0,0 +1,5 @@
extends TileEntity;
constructor () = 0xcfa78;
property Container container = 0x30;

View File

@ -0,0 +1 @@
virtual-method void postProcess(ChunkSource *chunk_source, int chunk_x, int chunk_y) = 0x14;

View File

@ -0,0 +1,3 @@
method std::string parse(ConnectedClient *client, std::string *command) = 0x6aa8c;
property Minecraft *minecraft = 0x18;

7
symbols/src/Common.def Normal file
View File

@ -0,0 +1,7 @@
static-method std::string *getGameVersionString(std::string *version_suffix) = 0x15068;
// These are not actually part of "Common", but they have to go somewhere.
static-method void renderCursor(float x, float y, Minecraft *minecraft) = 0x480c4;
static-method void sleepMs(int x) = 0x13cf4;
static-method int sdl_key_to_minecraft_key(int sdl_key) = 0x1243c;
static-method void anGenBuffers(int count, uint *buffers) = 0x5f28c;

0
symbols/src/Config.def Normal file
View File

View File

@ -0,0 +1,5 @@
size 0xc;
property uint sock = 0x0;
property std::string str = 0x4;
property int time = 0x8;

View File

@ -0,0 +1,2 @@
virtual-method void startOpen() = 0x24;
virtual-method void stopOpen() = 0x28;

View File

@ -0,0 +1,6 @@
vtable 0x10e1b8;
constructor (Container *container, int param_1) = 0x919a8;
virtual-method uchar *destructor() = 0x0;
property Container *container = 0x1c;

View File

@ -0,0 +1,5 @@
extends GameMode;
size 0x1c;
constructor (Minecraft *minecraft) = 0x1a044;

12
symbols/src/Entity.def Normal file
View File

@ -0,0 +1,12 @@
virtual-method bool hurt(Entity *attacker, int damage) = 0xa4;
property float x = 0x4;
property float y = 0x8;
property float z = 0xc;
property float yaw = 0x40;
property float pitch = 0x44;
property float old_x = 0x28;
property float old_y = 0x2c;
property float old_z = 0x30;
property float old_yaw = 0x48;
property float old_pitch = 0x4c;

View File

@ -0,0 +1,2 @@
constructor () = 0x6096c;
method void assign(uchar entity_id, EntityRenderer *renderer) = 0x6094c;

View File

@ -0,0 +1 @@
virtual-method void render(Entity *entity, float param_2, float param_3, float param_4, float param_5, float param_6) = 0x8;

View File

@ -0,0 +1 @@
extends LevelStorageSource;

View File

@ -0,0 +1,11 @@
method void addItem(ItemInstance *item_instance) = 0x92aa0;
virtual-method ItemInstance *getItem(int slot) = 0x8;
virtual-method void setItem(int slot, ItemInstance *item_instance) = 0xc;
virtual-method bool add(ItemInstance *item_instance) = 0x30;
method void clearSlot(int slot) = 0x922f8;
method void release(int slot) = 0x92058;
method void compressLinkedSlotList(int slot) = 0x92280;
property int *linked_slots = 0xc;
property int linked_slots_length = 0x14;
property bool is_creative = 0x24;

0
symbols/src/Font.def Normal file
View File

View File

@ -0,0 +1,2 @@
constructor () = 0xa0778;
method void addFurnaceRecipe(int input_item_id, ItemInstance *result) = 0xa0714;

View File

@ -0,0 +1,5 @@
extends Screen;
method int handleAddItem(int slot, ItemInstance *item) = 0x327a0;
property FurnaceTileEntity *tile_entity = 0x1d0;

View File

@ -0,0 +1,4 @@
extends TileEntity;
virtual-method ItemInstance *getItem(int slot) = 0x2c;
static-method int getBurnDuration(ItemInstance *item_instance) = 0xd33f8;

1
symbols/src/GameMode.def Normal file
View File

@ -0,0 +1 @@
virtual-method void releaseUsingItem(Player *player) = 0x5c;

View File

@ -0,0 +1,4 @@
method void render(float param_1) = 0x4a338;
method void setupCamera(float param_1, int param_2) = 0x489f8;
property Minecraft *minecraft = 0x4;

View File

@ -0,0 +1,3 @@
extends Tile;
vtable 0x1115a8;

17
symbols/src/Gui.def Normal file
View File

@ -0,0 +1,17 @@
size 0xa74;
extends GuiComponent;
method void tick() = 0x27778;
method void handleClick(int param_2, int param_3, int param_4) = 0x2599c;
method void renderOnSelectItemNameText(int param_1, Font *font, int param_2) = 0x26aec;
method void renderToolBar(float param_1, int param_2, int param_3) = 0x26c30;
method void renderChatMessages(int y_offset, uint max_messages, bool disable_fading, Font *font) = 0x273d8;
method void onConfigChanged(Config *config) = 0x255bc;
method void addMessage(std::string *text) = 0x27820;
property Minecraft *minecraft = 0x9f4;
property float selected_item_text_timer = 0x9fc;
// Globals
static-property float InvGuiScale = 0x135d98;

View File

@ -0,0 +1,2 @@
method void blit(int x_dest, int y_dest, int x_src, int y_src, int width_dest, int height_dest, int width_src, int height_src) = 0x282a4;
method void drawCenteredString(Font *font, std::string *text, int x, int y, int color) = 0x2821c;

View File

@ -0,0 +1,4 @@
extends Tile;
// Sand/Gravel Instant Falling
static-property bool instaFall = 0x180cc0;

10
symbols/src/HitResult.def Normal file
View File

@ -0,0 +1,10 @@
size 0x28;
property int type = 0x0;
property int x = 0x4;
property int y = 0x8;
property int z = 0xc;
property int side = 0x10;
property Vec3 exact = 0x14;
property Entity *entity = 0x20;
property uchar unknown = 0x24;

View File

@ -0,0 +1,5 @@
extends MobRenderer;
vtable 0x107908;
property HumanoidModel *model = 0x14;

View File

@ -0,0 +1 @@
property bool is_sneaking = 0x236;

View File

@ -0,0 +1 @@
virtual-method int tickBuild(Player *player, uint *build_action_intention_return) = 0xc;

View File

@ -0,0 +1 @@
extends Button;

View File

@ -0,0 +1,3 @@
extends Screen;
vtable 0x1045f0;

View File

@ -0,0 +1,6 @@
extends FillingContainer;
method void selectSlot(int slot) = 0x8d13c;
method ItemInstance *getSelected() = 0x8d134;
property int selectedSlot = 0x28;

27
symbols/src/Item.def Normal file
View File

@ -0,0 +1,27 @@
static-method void initItems() = 0x94ed0;
vtable-size 0x98;
vtable 0x10f128;
size 0x24;
constructor (int id) = 0x99488;
virtual-method void setIcon(int texture_x, int texture_y) = 0x18;
virtual-method int getIcon(int auxiliary) = 0x14;
virtual-method int useOn(ItemInstance *item_instance, Player *player, Level *level, int x, int y, int z, int hit_side, float hit_x, float hit_y, float hit_z) = 0x20;
virtual-method void setDescriptionId(std::string *name) = 0x6c;
virtual-method std::string getDescriptionId(ItemInstance *item_instance) = 0x7c;
property int id = 0x4;
property bool is_stacked_by_data = 0x19;
property int category = 0x10;
property int max_damage = 0x8;
property int max_stack_size = 0x14;
// Items
static-property Item *flintAndSteel = 0x17ba70;
static-property Item *snowball = 0x17bbb0;
static-property Item *shears = 0x17bbf0;
static-property Item *egg = 0x17bbd0;
static-property Item *dye_powder = 0x17bbe0;
static-property Item *camera = 0x17bc14;

View File

@ -0,0 +1,12 @@
size 0xc;
constructor item(Item *item) = 0x9992c;
constructor tile(Tile *item) = 0x998e4;
constructor tile_extra(Tile *item, int count, int auxiliary) = 0x99918;
constructor item_extra(Item *item, int count, int auxiliary) = 0x99960;
method int getMaxStackSize() = 0x99ac8;
property int count = 0x0;
property int id = 0x4;
property int auxiliary = 0x8;

View File

@ -0,0 +1,3 @@
static-method void renderGuiItem_one(Font *font, Textures *textures, ItemInstance *item_instance, float param_1, float param_2, bool param_3) = 0x63e58;
static-method void renderGuiItem_two(Font *font, Textures *textures, ItemInstance *item_instance, float param_1, float param_2, float param_3, float param_4, bool param_5) = 0x63be0;
static-method void renderGuiItemCorrect(Font *font, Textures *textures, ItemInstance *item_instance, int param_1, int param_2) = 0x639a0;

View File

@ -0,0 +1 @@
extends LargeFeature;

View File

@ -0,0 +1 @@
virtual-method void apply(ChunkSource *chunk_source, Level *level, int chunk_x, int chunk_y, uchar *chunk_data, int unused) = 0x8;

3
symbols/src/LeafTile.def Normal file
View File

@ -0,0 +1,3 @@
extends Tile;
vtable 0x1128c8;

10
symbols/src/Level.def Normal file
View File

@ -0,0 +1,10 @@
extends LevelSource;
vtable 0x108de0;
method void saveLevelData() = 0xa2e94;
method void setTileAndData(int x, int y, int z, int id, int data) = 0xa38b4;
method HitResult clip(uchar *param_1, uchar *param_2, bool clip_liquids, bool param_3) = 0xa3db0;
method void addParticle(std::string *particle, float x, float y, float z, float deltaX, float deltaY, float deltaZ, int count) = 0xa449c;
property std::vector<ServerPlayer*> players = 0x60;

View File

@ -0,0 +1 @@
method uint getSpawnMobs() = 0xbabec;

View File

@ -0,0 +1,7 @@
method void render(Mob *mob, int param_1, float delta) = 0x4f710;
method void renderDebug(AABB *aabb, float delta) = 0x4d310;
method void generateSky() = 0x4d0d4;
method void renderHitSelect(Player *player, HitResult *hit_result, int i, void *vp, float f) = 0x4e318;
method void renderHitOutline(Player *player, HitResult *hit_result, int i, void *vp, float f) = 0x4dc14;
property Minecraft *minecraft = 0x4;

View File

@ -0,0 +1,4 @@
size 0x8;
property int seed = 0x0;
property int game_type = 0x4;

View File

@ -0,0 +1,3 @@
virtual-method int getTile(int x, int y, int z) = 0x8;
virtual-method Material *getMaterial(int x, int y, int z) = 0x18;
virtual-method Biome *getBiome(int x, int z) = 0x24;

View File

@ -0,0 +1 @@
virtual-method void deleteLevel(std::string *level_name) = 0x20;

View File

@ -0,0 +1,3 @@
extends Tile;
vtable 0x114d78;

View File

@ -0,0 +1,5 @@
extends Player;
vtable 0x106230;
property Minecraft *minecraft = 0xc90;

View File

@ -0,0 +1,5 @@
extends Packet;
vtable 0x108dc0;
property RakNet_RakString username = 0xc;

4
symbols/src/Material.def Normal file
View File

@ -0,0 +1,4 @@
virtual-method bool isSolid() = 0x8;
// Globals
static-property Material *Material_stone = 0x180a9c;

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