More Feature Flags!

This commit is contained in:
TheBrokenRail 2024-11-22 03:07:54 -05:00
parent e1d9fc492b
commit 67ceb4ad00
13 changed files with 141 additions and 110 deletions

View File

@ -71,6 +71,9 @@
* `Fix Camera Functionality`
* `Property Scale Animated Textures`
* `Enable Text Input`
* `Update Default Options`
* `Fix options.txt Loading/Saving`
* `Fix Reloading Textures On Resize`
* Split Up `Remove Creative Mode Restrictions` Feature Flag
* `Remove Creative Mode Restrictions` (Disabled By Default)
* `Display Slot Count In Creative Mode` (Disabled By Default)

View File

@ -116,6 +116,7 @@ static std::string get_label(const FlagNode &node) {
}
void ConfigurationUI::draw_advanced() const {
if (ImGui::BeginChild("Features", ImVec2(0, 0), ImGuiChildFlags_Borders, ImGuiWindowFlags_HorizontalScrollbar)) {
// Categories
for (FlagNode &category : state.flags.root.children) {
std::string label = get_label(category);
if (ImGui::CollapsingHeader(label.c_str())) {

View File

@ -29,7 +29,7 @@ void *reborn_thunk_enabler(void *target, void *thunk);
// Replace All Calls To start With target Within [to, from)
void overwrite_calls_within_manual(void *from, void *to, void *start, void *target);
template <typename T>
void _overwrite_calls_within(void *from, void *to, T *start, typename T::ptr_type target) {
void overwrite_calls_within(void *from, void *to, T *start, typename T::ptr_type target) {
overwrite_calls_within_manual(from, to, (void *) start->get(), (void *) target);
}
@ -51,4 +51,4 @@ void patch_vtable(const T *start, typename T::ptr_type target) {
WARN("Use overwrite_calls() Instead!");
}
patch_address((void *) start->get_vtable_addr(), (void *) target);
}
}

View File

@ -124,6 +124,8 @@ CATEGORY Bug Fixes
TRUE Fix Switching Perspective While Sneaking
TRUE Fix Crash When Generating Certain Seeds
TRUE Fix Sugar Position In Hand
TRUE Fix Reloading Textures On Resize
TRUE Fix options.txt Loading/Saving
CATEGORY Logging
FALSE Log FPS
TRUE Log Chat Messages
@ -133,4 +135,5 @@ CATEGORY Miscellaneous
TRUE Fullscreen Support
TRUE Always Save Chest Tile Entities
TRUE Screenshot Support
TRUE Fix Camera Functionality
TRUE Fix Camera Functionality
TRUE Update Default Options

View File

@ -1,5 +1,5 @@
#pragma once
extern "C" {
int creative_is_restricted();
bool creative_is_restricted();
}

View File

@ -95,11 +95,16 @@ static TileItem *Tile_initTiles_TileItem_injection(TileItem *tile_item, int32_t
}
// Check Restriction Status
static int is_restricted = 1;
int creative_is_restricted() {
static bool is_restricted = true;
bool creative_is_restricted() {
return is_restricted;
}
// Allow Creative Players To Drop Items
static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(__attribute__((unused)) Minecraft *minecraft) {
return false;
}
// Init
void init_creative() {
// Add Extra Items To Creative Inventory (Only Replace Specific Function Call)
@ -128,8 +133,16 @@ void init_creative() {
patch((void *) 0x99010, nop_patch);
// Allow Nether Reactor
patch((void *) 0xc0290, nop_patch);
// Item Dropping
void *addr = (void *) 0x27800;
const void *func = extract_from_bl_instruction((unsigned char *) addr);
if (func == Minecraft_isCreativeMode->backup) {
overwrite_call(addr, (void *) Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection);
} else {
// Handled By input/misc.cpp
}
// Disable Other Restrictions
is_restricted = 0;
is_restricted = false;
}
// Inventory Behavior

View File

@ -9,9 +9,6 @@
#include <mods/creative/creative.h>
#include <mods/misc/misc.h>
// Enable Miscellaneous Input Fixes
static int enable_misc = 0;
// Handle Back Button Presses
static void _handle_back(Minecraft *minecraft) {
// If Minecraft's Level property is initialized, but Minecraft's Player property is nullptr, then Minecraft::handleBack may crash.
@ -50,7 +47,7 @@ static bool InBedScreen_handleBackEvent_injection(InBedScreen *screen, const boo
// Block UI Interaction When Mouse Is Locked
static bool Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection(Minecraft *minecraft) {
const bool is_in_game = minecraft->screen == nullptr || minecraft->screen->vtable == (Screen_vtable *) Touch_IngameBlockSelectionScreen_vtable::base;
if (!enable_misc || (media_SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF && is_in_game)) {
if (media_SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF && is_in_game) {
// Call Original Method
return creative_is_restricted() && minecraft->isCreativeMode();
} else {
@ -69,8 +66,7 @@ static void Gui_handleClick_injection(Gui_handleClick_t original, Gui *gui, cons
// Init
void _init_misc() {
enable_misc = feature_has("Miscellaneous Input Fixes", server_disabled);
if (enable_misc) {
if (feature_has("Miscellaneous Input Fixes", server_disabled)) {
// Fix OptionsScreen Ignoring The Back Button
patch_vtable(OptionsScreen_handleBackEvent, OptionsScreen_handleBackEvent_injection);
// Fix "Sleeping Beauty" Bug
@ -86,7 +82,7 @@ void _init_misc() {
return false;
}
});
// Disable Item Dropping Using The Cursor When Cursor Is Hidden
overwrite_call((void *) 0x27800, (void *) Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection);
}
// Disable Item Dropping Using The Cursor When Cursor Is Hidden
overwrite_call((void *) 0x27800, (void *) Gui_tickItemDrop_Minecraft_isCreativeMode_call_injection);
}

View File

@ -546,12 +546,19 @@ void _init_misc_graphics() {
}
// Modify Entity Rendering
overwrite_call((void *) 0x606c0, (void *) EntityRenderDispatcher_render_EntityRenderer_render_injection);
bool hijack_entity_rendering = false;
should_render_fire = feature_has("Render Fire In Third-Person", server_disabled);
if (should_render_fire) {
hijack_entity_rendering = true;
}
should_render_shadows = feature_has("Render Entity Shadows", server_disabled);
if (should_render_shadows) {
overwrite_calls(EntityRenderDispatcher_assign, EntityRenderDispatcher_assign_injection);
overwrite_calls(ArmorScreen_renderPlayer, ArmorScreen_renderPlayer_injection);
hijack_entity_rendering = true;
}
if (hijack_entity_rendering) {
overwrite_call((void *) 0x606c0, (void *) EntityRenderDispatcher_render_EntityRenderer_render_injection);
}
// Slightly Nicer Water Rendering

View File

@ -2,6 +2,7 @@
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <libreborn/patch.h>
#include <libreborn/config.h>
@ -40,15 +41,6 @@ static int get_render_distance() {
}
}
// Get Custom Username
static const char *get_username() {
const char *username = getenv(MCPI_USERNAME_ENV);
if (username == nullptr) {
username = "StevePi";
}
return username;
}
static int render_distance;
// Configure Options
Options *stored_options = nullptr;
@ -59,9 +51,6 @@ static void Options_initDefaultValue_injection(Options_initDefaultValue_t origin
// Default Graphics Settings
options->fancy_graphics = true;
options->ambient_occlusion = true;
// Store
stored_options = options;
}
static void Minecraft_init_injection(Minecraft_init_t original, Minecraft *minecraft) {
// Call Original Method
@ -72,6 +61,9 @@ static void Minecraft_init_injection(Minecraft_init_t original, Minecraft *minec
options->split_controls = true;
// Render Distance
options->render_distance = render_distance;
// Store
stored_options = options;
}
// Smooth Lighting
@ -89,9 +81,10 @@ static void Options_save_Options_addOptionToSaveOutput_injection(Options *option
// Call Original Method
options->addOptionToSaveOutput(data, option, value);
// Save Smooth Lighting
options->addOptionToSaveOutput(data, "gfx_ao", options->ambient_occlusion);
// Save Fancy Graphics
options->addOptionToSaveOutput(data, "gfx_fancygraphics", options->fancy_graphics);
// Save 3D Anaglyph
options->addOptionToSaveOutput(data, "gfx_anaglyph", options->anaglyph_3d);
@ -100,36 +93,67 @@ static void Options_save_Options_addOptionToSaveOutput_injection(Options *option
options_file->save(data);
}
// MCPI's OptionsFile::getOptionStrings is broken, this is the version in v0.7.0
static std::vector<std::string> OptionsFile_getOptionStrings_injection(__attribute__((unused)) OptionsFile_getOptionStrings_t original, OptionsFile *options_file) {
// MCPI's OptionsFile::getOptionStrings is broken, this is modified from the version in v0.7.0
static std::vector<std::string> OptionsFile_getOptionStrings_v2(OptionsFile *options_file) {
// Get options.txt Path
const std::string path = options_file->options_txt_path;
// Parse
std::vector<std::string> ret;
FILE *stream = fopen(path.c_str(), "r");
if (stream != nullptr) {
char line[128];
while (fgets(line, 0x80, stream) != nullptr) {
const size_t sVar1 = strlen(line);
if (2 < sVar1) {
std::ifstream stream(path, std::ios::binary);
if (stream) {
std::string line;
while (std::getline(stream, line)) {
if (!line.empty()) {
std::stringstream string_stream(line);
while (true) {
std::string data;
std::getline(string_stream, data, ':');
const int iVar2 = data.find_last_not_of(" \n\r\t");
data.erase(iVar2 + 1);
if (data.length() == 0) {
break;
}
ret.push_back(data);
std::string part;
while (std::getline(string_stream, part, ':')) {
ret.push_back(part);
}
}
}
fclose(stream);
stream.close();
}
return ret;
}
// Replacement Of Options::update
static void Options_update_injection(__attribute__((unused)) Options_update_t original, Options *self) {
const std::vector<std::string> strings = OptionsFile_getOptionStrings_v2(&self->options_file);
for (std::vector<std::string>::size_type i = 0; i < strings.size(); i++) {
// Read
const std::string key = strings[i++];
if (i == strings.size()) {
// Missing Value
break;
}
const std::string value = strings[i];
if (key == "mp_server_visible_default") {
Options::readBool(value, self->server_visible);
} else if (key == "game_difficulty") {
int &difficulty = self->game_difficulty;
Options::readInt(value, difficulty);
constexpr int normal_difficulty = 2;
if (difficulty != 0 && difficulty != normal_difficulty) {
difficulty = normal_difficulty;
}
} else if (key == "ctrl_invertmouse") {
Options::readBool(value, self->invert_mouse);
} else if (key == "ctrl_islefthanded") {
Options::readBool(value, self->lefty);
} else if (key == "gfx_ao") {
Options::readBool(value, self->ambient_occlusion);
} else if (key == "gfx_fancygraphics") {
Options::readBool(value, self->fancy_graphics);
} else if (key == "gfx_anaglyph") {
Options::readBool(value, self->anaglyph_3d);
} else if (key == "ctrl_usetouchscreen" || key == "feedback_vibration") {
// Skip
} else {
WARN("Unknown Option: %s", key.c_str());
}
}
}
// Get New options.txt Path
static const char *get_new_options_txt_path() {
static std::string path = "";
@ -153,17 +177,21 @@ void init_options() {
DEBUG("Setting Render Distance: %i", render_distance);
// Set Options
overwrite_calls(Options_initDefaultValue, Options_initDefaultValue_injection);
if (feature_has("Update Default Options", server_disabled)) {
overwrite_calls(Options_initDefaultValue, Options_initDefaultValue_injection);
}
overwrite_calls(Minecraft_init, Minecraft_init_injection);
// Change Username
const char *username = get_username();
DEBUG("Setting Username: %s", username);
if (strcmp(Strings::default_username, "StevePi") != 0) {
ERR("Default Username Is Invalid");
const char *username = getenv(MCPI_USERNAME_ENV);
if (username != nullptr) {
DEBUG("Setting Username: %s", username);
if (strcmp(Strings::default_username, "StevePi") != 0) {
ERR("Default Username Is Invalid");
}
static std::string safe_username = to_cp437(username);
patch_address((void *) &Strings::default_username, (void *) safe_username.c_str());
}
static std::string safe_username = to_cp437(username);
patch_address((void *) &Strings::default_username, (void *) safe_username.c_str());
// Disable Autojump By Default
if (feature_has("Disable Autojump By Default", server_disabled)) {
@ -181,54 +209,21 @@ void init_options() {
// Smooth Lighting
overwrite_calls(TileRenderer_tesselateBlockInWorld, TileRenderer_tesselateBlockInWorld_injection);
// NOP
unsigned char nop_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
// options.txt
if (feature_has("Fix options.txt Loading/Saving", server_disabled)) {
// Actually Save options.txt
overwrite_call((void *) 0x197fc, (void *) Options_save_Options_addOptionToSaveOutput_injection);
// Fix 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
patch_address((void *) &Strings::options_txt_fopen_mode_when_loading, (void *) "r");
// Fix Loading
overwrite_calls(Options_update, Options_update_injection);
// Actually Save options.txt
overwrite_call((void *) 0x197fc, (void *) Options_save_Options_addOptionToSaveOutput_injection);
// Fix 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
patch_address((void *) &Strings::options_txt_fopen_mode_when_loading, (void *) "r");
// Fix OptionsFile::getOptionStrings
overwrite_calls(OptionsFile_getOptionStrings, OptionsFile_getOptionStrings_injection);
// Sensitivity Loading/Saving Is Broken, Disable It
patch((void *) 0x1931c, nop_patch);
patch((void *) 0x1973c, nop_patch);
// Unsplit Touch Controls Breaks Things, Never Load/Save It
unsigned char cmp_r0_r0_patch[4] = {0x00, 0x00, 0x50, 0xe1}; // "cmp r0, r0"
patch((void *) 0x19378, cmp_r0_r0_patch);
patch((void *) 0x197cc, nop_patch);
// Custom Username Is Loaded Manually, Disable Loading From options.txt
patch((void *) 0x192ac, nop_patch);
// Replace "feedback_vibration" Loading/Saving With "gfx_ao"
{
// Replace String
patch_address((void *) &Strings::feedback_vibration_options_txt_name, (void *) "gfx_ao");
// Loading
constexpr 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);
// Saving
unsigned char gfx_ao_saving_patch[4] = {offset, 0x30, 0xd4, 0xe5}; // "ldrb r3, [r4, #OFFSET]"
patch((void *) 0x197f8, gfx_ao_saving_patch);
}
// Replace "gfx_lowquality" Loading With "gfx_anaglyph"
{
// Replace String
patch_address((void *) &Strings::gfx_lowquality_options_txt_name, (void *) "gfx_anaglyph");
// Loading
constexpr 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);
// Disable Loading Side Effects
patch((void *) 0x19414, nop_patch);
patch((void *) 0x1941c, nop_patch);
// Disable Saving Some Settings
unsigned char nop_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
patch((void *) 0x1973c, nop_patch); // "ctrl_sensitivity"
patch((void *) 0x197cc, nop_patch); // "ctrl_usetouchjoypad"
}
// UI

View File

@ -224,5 +224,9 @@ void _init_textures_lava(const bool animated_water_param, const bool animated_la
animated_water = animated_water_param;
animated_lava = animated_lava_param;
animated_fire = animated_fire_param;
if (!animated_water) {
unsigned char disable_water_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
patch((void *) 0x17094, disable_water_patch);
}
overwrite_call((void *) 0x170b4, (void *) Textures_addDynamicTexture_injection);
}

View File

@ -164,12 +164,6 @@ void init_textures() {
if (animated_water || animated_lava || animated_fire) {
// Tick Dynamic Textures
misc_run_on_tick(Minecraft_tick_injection);
// Disable Animated Water If Set
if (!animated_water) {
unsigned char disable_water_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
patch((void *) 0x17094, disable_water_patch);
patch((void *) 0x170b4, disable_water_patch);
}
// Animated Lava
_init_textures_lava(animated_water, animated_lava, animated_fire);
}
@ -178,6 +172,8 @@ void init_textures() {
overwrite_calls(AppPlatform_linux_loadTexture, AppPlatform_linux_loadTexture_injection);
// Stop Reloading Textures On Resize
unsigned char texture_reset_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
patch((void *) 0x126b4, texture_reset_patch);
if (feature_has("Fix Reloading Textures On Resize", server_disabled)) {
unsigned char texture_reset_patch[4] = {0x00, 0xf0, 0x20, 0xe3}; // "nop"
patch((void *) 0x126b4, texture_reset_patch);
}
}

View File

@ -183,18 +183,25 @@ void init_title_screen() {
}
// Better Scaling And Position
bool hijack_version_rendering = false;
if (feature_has("Improved Classic Title Positioning", server_disabled)) {
overwrite_call((void *) 0x3956c, (void *) StartMenuScreen_render_Textures_getTemporaryTextureData_injection_modern);
overwrite_call((void *) 0x39528, (void *) StartMenuScreen_render_Screen_renderBackground_injection);
hijack_version_rendering = true;
adjust_version_y = get_version_y;
}
overwrite_call((void *) 0x39728, (void *) StartMenuScreen_render_GuiComponent_drawString_injection);
// Add Splashes
if (feature_has("Add Splashes", server_disabled)) {
hijack_version_rendering = true;
_init_splashes();
}
// Adjust And Record Version String Rendering
if (hijack_version_rendering) {
overwrite_call((void *) 0x39728, (void *) StartMenuScreen_render_GuiComponent_drawString_injection);
}
// Init Welcome Screen
if (feature_has("Add Welcome Screen", server_disabled)) {
_init_welcome();

View File

@ -4,6 +4,10 @@ method void initDefaultValue() = 0x18a54;
method bool getBooleanValue(Options_Option *option) = 0x1cd74;
method void addOptionToSaveOutput(std::vector<std::string> *data, std::string option, int value) = 0x195e4;
method void save() = 0x1966c;
method void update() = 0x19248;
static-method bool readBool(const std::string &str, bool &out) = 0x19168;
static-method bool readInt(const std::string &str, int &out) = 0x19014;
property OptionsFile options_file = 0x10c;
property bool fancy_graphics = 0x17;
@ -18,3 +22,5 @@ property int sound = 0x4;
property bool debug = 0xee;
property bool server_visible = 0x104;
property std::string username = 0x100;
property bool invert_mouse = 0xc;
property bool lefty = 0x1a;