Attack Of The Templates!
This commit is contained in:
parent
97bc124d72
commit
b129f0a503
2
dependencies/symbol-processor/src
vendored
2
dependencies/symbol-processor/src
vendored
@ -1 +1 @@
|
||||
Subproject commit fbb9b6d6da1a9dfa9290d420d1b2c34f91026111
|
||||
Subproject commit eb49f25fa45842ebff448cbadd347c883e66efb6
|
@ -241,6 +241,7 @@ void setup_crash_report() {
|
||||
|
||||
// Close Log File
|
||||
reborn_close_log();
|
||||
unsetenv(MCPI_LOG_ENV);
|
||||
|
||||
// Show Crash Log
|
||||
#ifndef MCPI_HEADLESS_MODE
|
||||
|
@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Patching Functions
|
||||
|
||||
@ -12,74 +10,127 @@ void reborn_init_patch();
|
||||
|
||||
// Replace Call Located At start With A Call To target
|
||||
void _overwrite_call(const char *file, int line, void *start, void *target);
|
||||
#define overwrite_call(start, target) _overwrite_call(__FILE__, __LINE__, start, target)
|
||||
#define overwrite_call(...) \
|
||||
_overwrite_call(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
||||
#define _setup_fancy_overwrite(start, name, target) \
|
||||
static name##_t _original_for_##target = start; \
|
||||
static name##_t _helper_for_##target = __overwrite_helper_for_##name(target, _original_for_##target)
|
||||
// Make Sure Function Is Only Called Once
|
||||
template <int>
|
||||
static void _only_call_once() {
|
||||
static bool _has_run = false;
|
||||
if (_has_run) {
|
||||
IMPOSSIBLE();
|
||||
}
|
||||
_has_run = true;
|
||||
}
|
||||
|
||||
// Replace All Calls To Method start With target
|
||||
void *_overwrite_calls(const char *file, int line, void *start, void *target);
|
||||
#define overwrite_calls_manual(start, target) _overwrite_calls(__FILE__, __LINE__, start, target)
|
||||
#define overwrite_calls(start, target) \
|
||||
{ \
|
||||
_setup_fancy_overwrite(start, start, target); \
|
||||
start = (start##_t) overwrite_calls_manual((void *) start, (void *) _helper_for_##target); \
|
||||
void *_overwrite_calls_manual(const char *file, int line, void *start, void *target);
|
||||
#define overwrite_calls_manual(...) \
|
||||
_overwrite_calls_manual(__FILE__, __LINE__, __VA_ARGS__)
|
||||
template <int call_id, typename start_t, typename overwrite_t>
|
||||
static void _overwrite_calls(const char *file, int line, start_t (*create_helper)(overwrite_t, start_t), start_t &start, overwrite_t target) {
|
||||
_only_call_once<call_id>();
|
||||
start_t helper = create_helper(target, start);
|
||||
start = (start_t) _overwrite_calls_manual(file, line, (void *) start, (void *) helper);
|
||||
}
|
||||
#define overwrite_calls(start, ...) \
|
||||
_overwrite_calls< \
|
||||
__COUNTER__, \
|
||||
start##_t, \
|
||||
__overwrite_##start##_t \
|
||||
>( \
|
||||
__FILE__, __LINE__, \
|
||||
__create_overwrite_helper_for_##start, \
|
||||
start, \
|
||||
__VA_ARGS__ \
|
||||
)
|
||||
|
||||
// Replace All Calls To Virtual Method start With target
|
||||
#define _check_if_method_is_new(name) \
|
||||
{ \
|
||||
if (!__is_new_method_##name()) { \
|
||||
ERR("Method Is Not \"New\""); \
|
||||
} \
|
||||
template <int call_id, typename start_t, typename overwrite_t>
|
||||
static void _overwrite_virtual_calls(const char *file, int line, start_t (*create_helper)(overwrite_t, start_t), bool (*is_overwritable)(), start_t start, overwrite_t target) {
|
||||
_only_call_once<call_id>();
|
||||
if (!is_overwritable()) {
|
||||
ERR("Virtual Method Is Not Overwritable");
|
||||
}
|
||||
#define overwrite_virtual_calls(start, target) \
|
||||
{ \
|
||||
_check_if_method_is_new(start); \
|
||||
_setup_fancy_overwrite(*start##_vtable_addr, start, target); \
|
||||
overwrite_calls_manual((void *) *start##_vtable_addr, (void *) _helper_for_##target); \
|
||||
start_t helper = create_helper(target, start);
|
||||
_overwrite_calls_manual(file, line, (void *) start, (void *) helper);
|
||||
}
|
||||
#define overwrite_virtual_calls(start, ...) \
|
||||
_overwrite_virtual_calls< \
|
||||
__COUNTER__, \
|
||||
start##_t, \
|
||||
__overwrite_##start##_t \
|
||||
>( \
|
||||
__FILE__, __LINE__, \
|
||||
__create_overwrite_helper_for_##start, \
|
||||
__is_overwritable_##start, \
|
||||
*start##_vtable_addr, \
|
||||
__VA_ARGS__ \
|
||||
)
|
||||
|
||||
// Replace All Calls To start With target Within [to, from)
|
||||
void _overwrite_calls_within(const char *file, int line, void *from, void *to, void *start, void *target);
|
||||
#define overwrite_calls_within_manual(from, to, start, target) _overwrite_calls_within(__FILE__, __LINE__, from, to, start, target)
|
||||
#define overwrite_calls_within(from, to, start, target) \
|
||||
{ \
|
||||
start##_t type_check = target; \
|
||||
overwrite_calls_within_manual(from, to, (void *) start, (void *) type_check); \
|
||||
void _overwrite_calls_within_manual(const char *file, int line, void *from, void *to, void *start, void *target);
|
||||
#define overwrite_calls_within_manual(...) \
|
||||
_overwrite_calls_within(__FILE__, __LINE__, __VA_ARGS__)
|
||||
template <typename start_t>
|
||||
void _overwrite_calls_within(const char *file, int line, void *from, void *to, start_t start, start_t target) {
|
||||
_overwrite_calls_within_manual(file, line, from, to, (void *) start, (void *) target);
|
||||
}
|
||||
#define overwrite_calls_within(from, to, start, ...) \
|
||||
_overwrite_calls_within< \
|
||||
start##_t \
|
||||
>( \
|
||||
__FILE__, __LINE__, \
|
||||
from, to, \
|
||||
start, \
|
||||
__VA_ARGS__ \
|
||||
)
|
||||
|
||||
// Get Target Address From BL Instruction
|
||||
void *extract_from_bl_instruction(unsigned char *from);
|
||||
|
||||
// Replace Method start With target
|
||||
void _overwrite(const char *file, int line, void *start, void *target);
|
||||
#define overwrite_manual(start, target) _overwrite(__FILE__, __LINE__, (void *) start, (void *) target)
|
||||
#define overwrite(start, target) \
|
||||
{ \
|
||||
start##_t type_check = target; \
|
||||
overwrite_manual((void *) start, (void *) type_check); \
|
||||
void _overwrite_manual(const char *file, int line, void *start, void *target);
|
||||
#define overwrite_manual(...) \
|
||||
_overwrite(__FILE__, __LINE__, __VA_ARGS__)
|
||||
template <typename start_t>
|
||||
void _overwrite(const char *file, int line, start_t start, start_t target) {
|
||||
_overwrite_manual(file, line, (void *) start, (void *) target);
|
||||
}
|
||||
#define overwrite(start, ...) \
|
||||
_overwrite< \
|
||||
start##_t \
|
||||
>( \
|
||||
__FILE__, __LINE__, \
|
||||
start, \
|
||||
__VA_ARGS__ \
|
||||
)
|
||||
|
||||
// Patch Instruction
|
||||
void _patch(const char *file, int line, void *start, unsigned char patch[4]);
|
||||
#define patch(start, patch) _patch(__FILE__, __LINE__, start, patch)
|
||||
#define patch(...) \
|
||||
_patch(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
||||
// Patch 4 Bytes Of Data
|
||||
void _patch_address(const char *file, int line, void *start, void *target);
|
||||
#define patch_address(start, target) _patch_address(__FILE__, __LINE__, (void *) start, (void *) target)
|
||||
#define patch_address(...) \
|
||||
_patch_address(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
||||
// Patch VTable Entry
|
||||
// This does not affect sub-classes.
|
||||
#define patch_vtable(start, target) \
|
||||
{ \
|
||||
start##_t type_check = target; \
|
||||
patch_address(start##_vtable_addr, (void *) type_check); \
|
||||
template <typename start_t>
|
||||
void _patch_vtable(const char *file, int line, start_t *start, start_t target) {
|
||||
_patch_address(file, line, (void *) start, (void *) target);
|
||||
}
|
||||
#define patch_vtable(start, ...) \
|
||||
_patch_vtable< \
|
||||
start##_t \
|
||||
>( \
|
||||
__FILE__, __LINE__, \
|
||||
start##_vtable_addr, \
|
||||
__VA_ARGS__ \
|
||||
)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -77,7 +77,7 @@ static int _overwrite_calls_within_internal(const char *file, int line, void *fr
|
||||
#define TEXT_END 0x1020c0
|
||||
// Overwrite All B(L) Intrusctions That Target The Specified Address
|
||||
#define NO_CALLSITE_ERROR "(%s:%i) Unable To Find Callsites For %p"
|
||||
void *_overwrite_calls(const char *file, int line, void *start, void *target) {
|
||||
void *_overwrite_calls_manual(const char *file, int line, void *start, void *target) {
|
||||
// Add New Target To Code Block
|
||||
void *code_block = update_code_block(target);
|
||||
|
||||
@ -97,7 +97,7 @@ void *_overwrite_calls(const char *file, int line, void *start, void *target) {
|
||||
// Return
|
||||
return code_block;
|
||||
}
|
||||
void _overwrite_calls_within(const char *file, int line, void *from /* inclusive */, void *to /* exclusive */, void *target, void *replacement) {
|
||||
void _overwrite_calls_within_manual(const char *file, int line, void *from /* inclusive */, void *to /* exclusive */, void *target, void *replacement) {
|
||||
// Add New Target To Code Block
|
||||
void *code_block = update_code_block(replacement);
|
||||
|
||||
@ -113,7 +113,7 @@ void _overwrite_calls_within(const char *file, int line, void *from /* inclusive
|
||||
}
|
||||
|
||||
// Overwrite Function
|
||||
void _overwrite(const char *file, int line, void *start, void *target) {
|
||||
void _overwrite_manual(const char *file, int line, void *start, void *target) {
|
||||
// Replace the function's start with a call
|
||||
// to the replacement function.
|
||||
_overwrite_call_internal(file, line, start, target, 1);
|
||||
|
@ -8,21 +8,53 @@ extern "C" {
|
||||
int32_t misc_get_real_selected_slot(Player *player);
|
||||
void misc_render_background(int color, Minecraft *minecraft, int x, int y, int width, int height);
|
||||
|
||||
typedef void (*misc_update_function_Minecraft_t)(Minecraft *obj);
|
||||
void misc_run_on_update(misc_update_function_Minecraft_t function); // obj == Minecraft *
|
||||
void misc_run_on_tick(misc_update_function_Minecraft_t function); // obj == Minecraft *
|
||||
typedef void (*misc_update_function_Recipes_t)(Recipes *obj);
|
||||
void misc_run_on_recipes_setup(misc_update_function_Recipes_t function); // obj == Recipes *
|
||||
typedef void (*misc_update_function_FurnaceRecipes_t)(FurnaceRecipes *obj);
|
||||
void misc_run_on_furnace_recipes_setup(misc_update_function_FurnaceRecipes_t function); // obj == FurnaceRecipes *
|
||||
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 misc_run_on_language_setup(misc_update_function_void_t function); // obj == NULL
|
||||
typedef bool (*misc_update_function_key_press_t)(Minecraft *minecrtaft, int key);
|
||||
void misc_run_on_game_key_press(misc_update_function_key_press_t function); // In-Game Key Presses Only
|
||||
|
||||
extern bool is_in_chat;
|
||||
}
|
||||
|
||||
#define misc_run_on_update(...) \
|
||||
overwrite_virtual_calls(Minecraft_update, [](Minecraft_update_t _original, Minecraft *_self) { \
|
||||
_original(_self); \
|
||||
(__VA_ARGS__)(_self); \
|
||||
})
|
||||
#define misc_run_on_tick(...) \
|
||||
overwrite_calls(Minecraft_tick, [](Minecraft_tick_t _original, Minecraft *_self, int _tick, int _max_ticks) { \
|
||||
_original(_self, _tick, _max_ticks); \
|
||||
(__VA_ARGS__)(_self); \
|
||||
})
|
||||
#define misc_run_on_recipes_setup(...) \
|
||||
overwrite_calls(Recipes_constructor, [](Recipes_constructor_t _original, Recipes *_self) { \
|
||||
_original(_self); \
|
||||
(__VA_ARGS__)(_self); \
|
||||
return _self; \
|
||||
})
|
||||
#define misc_run_on_furnace_recipes_setup(...) \
|
||||
overwrite_calls(FurnaceRecipes_constructor, [](FurnaceRecipes_constructor_t _original, FurnaceRecipes *_self) { \
|
||||
_original(_self); \
|
||||
(__VA_ARGS__)(_self); \
|
||||
return _self; \
|
||||
})
|
||||
#define misc_run_on_tiles_setup(...) \
|
||||
overwrite_calls(Tile_initTiles, [](Tile_initTiles_t _original) { \
|
||||
(__VA_ARGS__)(); \
|
||||
_original(); \
|
||||
})
|
||||
#define misc_run_on_items_setup(...) \
|
||||
overwrite_calls(Item_initItems, [](Item_initItems_t _original) { \
|
||||
_original(); \
|
||||
(__VA_ARGS__)(); \
|
||||
})
|
||||
#define misc_run_on_language_setup(...) \
|
||||
overwrite_calls(I18n_loadLanguage, [](I18n_loadLanguage_t _original, AppPlatform *_self, std::string _language_name) { \
|
||||
_original(_self, _language_name); \
|
||||
(__VA_ARGS__)(); \
|
||||
})
|
||||
#define misc_run_on_game_key_press(...) \
|
||||
overwrite_calls(Gui_handleKeyPressed, [](Gui_handleKeyPressed_t _original, Gui *_self, int _key) { \
|
||||
if ((__VA_ARGS__)(_self->minecraft, _key)) { \
|
||||
return; \
|
||||
} \
|
||||
_original(_self, _key); \
|
||||
})
|
||||
|
@ -207,7 +207,7 @@ static FoodItem *create_bucket(int32_t id, int32_t texture_x, int32_t texture_y,
|
||||
// Return
|
||||
return item;
|
||||
}
|
||||
static void Item_initItems_injection(__attribute__((unused)) void *null) {
|
||||
static void Item_initItems_injection() {
|
||||
bucket = create_bucket(69, 10, 4, "bucket");
|
||||
}
|
||||
|
||||
@ -340,7 +340,7 @@ static void FurnaceTileEntity_tick_ItemInstance_setNull_injection(ItemInstance *
|
||||
}
|
||||
|
||||
// Add the bucket name to the language file
|
||||
static void Language_injection(__attribute__((unused)) void *null) {
|
||||
static void Language_injection() {
|
||||
I18n::_strings.insert(std::make_pair("item.bucketMilk.name", "Milk Bucket"));
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ static void make_cake() {
|
||||
cake->setDescriptionId(&name);
|
||||
}
|
||||
|
||||
static void Tile_initTiles_injection(__attribute__((unused)) void *null) {
|
||||
static void Tile_initTiles_injection() {
|
||||
make_cake();
|
||||
}
|
||||
|
||||
|
@ -27,56 +27,6 @@
|
||||
} \
|
||||
}
|
||||
|
||||
// Run Functions On Update
|
||||
SETUP_CALLBACK(update, Minecraft);
|
||||
// Handle Custom Update Behavior
|
||||
static void Minecraft_update_injection(Minecraft_update_t original, Minecraft *minecraft) {
|
||||
// Call Original Method
|
||||
original(minecraft);
|
||||
|
||||
// Run Functions
|
||||
handle_misc_update(minecraft);
|
||||
}
|
||||
|
||||
// Run Functions On Tick
|
||||
SETUP_CALLBACK(tick, Minecraft);
|
||||
// Handle Custom Tick Behavior
|
||||
static void Minecraft_tick_injection(Minecraft_tick_t original, Minecraft *minecraft, int32_t param_1, int32_t param_2) {
|
||||
// Call Original Method
|
||||
original(minecraft, param_1, param_2);
|
||||
|
||||
// Run Functions
|
||||
handle_misc_tick(minecraft);
|
||||
}
|
||||
|
||||
// Run Functions On Recipes Setup
|
||||
SETUP_CALLBACK(recipes_setup, Recipes);
|
||||
// Handle Custom Recipes Setup Behavior
|
||||
static Recipes *Recipes_injection(Recipes_constructor_t original, Recipes *recipes) {
|
||||
// Call Original Method
|
||||
original(recipes);
|
||||
|
||||
// Run Functions
|
||||
handle_misc_recipes_setup(recipes);
|
||||
|
||||
// Return
|
||||
return recipes;
|
||||
}
|
||||
|
||||
// Run Functions On Furnace Recipes Setup
|
||||
SETUP_CALLBACK(furnace_recipes_setup, FurnaceRecipes);
|
||||
// Handle Custom Furnace Recipes Setup Behavior
|
||||
static FurnaceRecipes *FurnaceRecipes_injection(FurnaceRecipes_constructor_t original, FurnaceRecipes *recipes) {
|
||||
// Call Original Method
|
||||
original(recipes);
|
||||
|
||||
// Run Functions
|
||||
handle_misc_furnace_recipes_setup(recipes);
|
||||
|
||||
// Return
|
||||
return recipes;
|
||||
}
|
||||
|
||||
// Run Functions On Creative Inventory Setup
|
||||
SETUP_CALLBACK(creative_inventory_setup, FillingContainer);
|
||||
// Handle Custom Creative Inventory Setup Behavior
|
||||
@ -88,60 +38,6 @@ static void Inventory_setupDefault_FillingContainer_addItem_call_injection(Filli
|
||||
handle_misc_creative_inventory_setup(filling_container);
|
||||
}
|
||||
|
||||
// Run Functions On Tiles Setup
|
||||
SETUP_CALLBACK(tiles_setup, void);
|
||||
// Handle Custom Tiles Setup Behavior
|
||||
static void Tile_initTiles_injection(Tile_initTiles_t original) {
|
||||
// Run Functions
|
||||
handle_misc_tiles_setup(nullptr);
|
||||
|
||||
// Call Original Method
|
||||
original();
|
||||
}
|
||||
|
||||
// Run Functions On Items Setup
|
||||
SETUP_CALLBACK(items_setup, void);
|
||||
// Handle Custom Items Setup Behavior
|
||||
static void Item_initItems_injection(Item_initItems_t original) {
|
||||
// Call Original Method
|
||||
original();
|
||||
|
||||
// Run Functions
|
||||
handle_misc_items_setup(nullptr);
|
||||
}
|
||||
|
||||
// Run Functions On Language Setup
|
||||
SETUP_CALLBACK(language_setup, void);
|
||||
// Handle Custom Items Setup Behavior
|
||||
static void I18n_loadLanguage_injection(I18n_loadLanguage_t original, AppPlatform *app, std::string language_name) {
|
||||
// Call Original Method
|
||||
original(app, std::move(language_name));
|
||||
|
||||
// Run Functions
|
||||
handle_misc_language_setup(nullptr);
|
||||
}
|
||||
|
||||
// Run Functions On GUI Key Press
|
||||
STORE_CALLBACK(game_key_press, key_press)
|
||||
static bool handle_misc_game_key_press(Minecraft *minecraft, int key) {
|
||||
for (misc_update_function_key_press_t function : get_misc_game_key_press_functions()) {
|
||||
if (function(minecraft, key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Handle Key Presses
|
||||
static void Gui_handleKeyPressed_injection(Gui_handleKeyPressed_t original, Gui *self, int key) {
|
||||
// Run Functions
|
||||
if (handle_misc_game_key_press(self->minecraft, key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Call Original Method
|
||||
original(self, key);
|
||||
}
|
||||
|
||||
// Render Fancy Background
|
||||
void misc_render_background(int color, Minecraft *minecraft, int x, int y, int width, int height) {
|
||||
// https://github.com/ReMinecraftPE/mcpe/blob/f0d65eaecec1b3fe9c2f2b251e114a890c54ab77/source/client/gui/components/RolledSelectionList.cpp#L169-L179
|
||||
@ -166,20 +62,6 @@ void misc_render_background(int color, Minecraft *minecraft, int x, int y, int w
|
||||
|
||||
// Init
|
||||
void _init_misc_api() {
|
||||
// Handle Custom Update Behavior
|
||||
overwrite_virtual_calls(Minecraft_update, Minecraft_update_injection);
|
||||
// Handle Custom Tick Behavior
|
||||
overwrite_calls(Minecraft_tick, Minecraft_tick_injection);
|
||||
// Handle Custom Recipe Setup Behavior
|
||||
overwrite_calls(Recipes_constructor, Recipes_injection);
|
||||
overwrite_calls(FurnaceRecipes_constructor, FurnaceRecipes_injection);
|
||||
// Handle Custom Creative Inventory Setup Behavior
|
||||
overwrite_call((void *) 0x8e0fc, (void *) Inventory_setupDefault_FillingContainer_addItem_call_injection);
|
||||
// Handle Custom Item/Tile Init Behavior
|
||||
overwrite_calls(Tile_initTiles, Tile_initTiles_injection);
|
||||
overwrite_calls(Item_initItems, Item_initItems_injection);
|
||||
// Handle Custom Language Entries
|
||||
overwrite_calls(I18n_loadLanguage, I18n_loadLanguage_injection);
|
||||
// Handle Key Presses
|
||||
overwrite_calls(Gui_handleKeyPressed, Gui_handleKeyPressed_injection);
|
||||
}
|
||||
|
@ -822,10 +822,10 @@ void init_misc() {
|
||||
|
||||
#ifdef MCPI_HEADLESS_MODE
|
||||
// Don't Render Game In Headless Mode
|
||||
overwrite_manual(GameRenderer_render, nop);
|
||||
overwrite_manual(NinecraftApp_initGLStates, nop);
|
||||
overwrite_manual(Gui_onConfigChanged, nop);
|
||||
overwrite_manual(LevelRenderer_generateSky, nop);
|
||||
overwrite_manual((void *) GameRenderer_render, (void *) nop);
|
||||
overwrite_manual((void *) NinecraftApp_initGLStates, (void *) nop);
|
||||
overwrite_manual((void *) Gui_onConfigChanged, (void *) nop);
|
||||
overwrite_manual((void *) LevelRenderer_generateSky, (void *) nop);
|
||||
#else
|
||||
// Improved Cursor Rendering
|
||||
if (feature_has("Improved Cursor Rendering", server_disabled)) {
|
||||
@ -849,7 +849,7 @@ void init_misc() {
|
||||
|
||||
// Remove Forced GUI Lag
|
||||
if (feature_has("Remove Forced GUI Lag (Can Break Joining Servers)", server_enabled)) {
|
||||
overwrite_manual(Common_sleepMs, nop);
|
||||
overwrite_manual((void *) Common_sleepMs, (void *) nop);
|
||||
}
|
||||
|
||||
#ifndef MCPI_HEADLESS_MODE
|
||||
|
Loading…
Reference in New Issue
Block a user