diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index dca891e1..ca07b2bb 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -62,6 +62,8 @@ * `Fix Furnace Screen Visual Bug` (Enabled By Default) * `Fix Held Item Poking Through Screen Overlay` (Enabled By Default) * `Implement RaspberryJuice API` (Enabled By Default) + * `Fix HUD When Spectating Other Players` (Enabled By Default) + * `Fix Crash When Spectated Entity Is Removed` (Enabled By Default) * Existing Functionality (All Enabled By Default) * `Fix Screen Rendering When Hiding HUD` * `Sanitize Usernames` diff --git a/libreborn/src/util/env/flags/available-feature-flags b/libreborn/src/util/env/flags/available-feature-flags index 1f0e3ab7..8d73d90a 100644 --- a/libreborn/src/util/env/flags/available-feature-flags +++ b/libreborn/src/util/env/flags/available-feature-flags @@ -135,6 +135,9 @@ CATEGORY Bug Fixes TRUE Fix Crash When Generating Certain Seeds TRUE Close Editor When Sign Is Destroyed TRUE Close Current Screen On Death + CATEGORY API + TRUE Fix HUD When Spectating Other Players + TRUE Fix Crash When Spectated Entity Is Removed TRUE Fix Reloading Textures On Resize TRUE Fix options.txt Loading/Saving TRUE Fix Hanging When No Valid Spawn Point Exists diff --git a/mods/src/api/api.cpp b/mods/src/api/api.cpp index 1f56a32d..02edcb1a 100644 --- a/mods/src/api/api.cpp +++ b/mods/src/api/api.cpp @@ -292,7 +292,7 @@ std::string CommandServer_parse_injection(CommandServer_parse_t old, CommandServ std::string args_str = command.substr(arg_start + 1, cmd_end - arg_start - 1); // Redirect Player Namespace To The Entity One - if (server->minecraft->player != nullptr && cmd.starts_with(player_namespace) && cmd != "player.setting") { + if (server->minecraft->player != nullptr && cmd.starts_with(player_namespace) && cmd != (player_namespace + "setting")) { cmd = "entity." + cmd.substr(player_namespace.size()); args_str = std::to_string(server->minecraft->player->id) + arg_separator + args_str; } @@ -617,6 +617,33 @@ sign->lines[i] = get_input(line_##i); \ } } +// Fix HUD Spectating Other Players +template +static void ItemInHandRenderer_render_injection(const std::function &original, ItemInHandRenderer *self, Args... args) { + // "Fix" Current Player + LocalPlayer *&player = self->minecraft->player; + LocalPlayer *old_player = player; + Mob *camera = self->minecraft->camera; + if (camera && camera->isPlayer()) { + player = (LocalPlayer *) camera; + } + // Call Original Method + original(self, std::forward(args)...); + // Revert "Fix" + player = old_player; +} + +// Fix Crash When Camera Entity Is Removed +static void LevelRenderer_entityRemoved_injection(LevelRenderer *self, Entity *entity) { + // Call Original Method + LevelListener_entityRemoved->get(false)((LevelListener *) self, entity); + // Fix Camera + Minecraft *minecraft = self->minecraft; + if ((Entity *) minecraft->camera == entity) { + minecraft->camera = (Mob *) minecraft->player; + } +} + // Init void init_api() { if (feature_has("Implement RaspberryJuice API", server_enabled)) { @@ -626,4 +653,13 @@ void init_api() { overwrite_calls(ClientSideNetworkHandler_handle_MovePlayerPacket, ClientSideNetworkHandler_handle_MovePlayerPacket_injection); overwrite_call((void *) 0x6b6e8, Entity_moveTo, Entity_moveTo_injection); } + // Bug Fixes + if (feature_has("Fix HUD When Spectating Other Players", server_enabled)) { + overwrite_calls(ItemInHandRenderer_render, ItemInHandRenderer_render_injection); + overwrite_calls(ItemInHandRenderer_renderScreenEffect, ItemInHandRenderer_render_injection); + overwrite_calls(ItemInHandRenderer_tick, ItemInHandRenderer_render_injection<>); + } + if (feature_has("Fix Crash When Spectated Entity Is Removed", server_enabled)) { + patch_vtable(LevelRenderer_entityRemoved, LevelRenderer_entityRemoved_injection); + } } diff --git a/mods/src/chat/chat.cpp b/mods/src/chat/chat.cpp index b40e48bd..eeea963f 100644 --- a/mods/src/chat/chat.cpp +++ b/mods/src/chat/chat.cpp @@ -47,7 +47,7 @@ void chat_send_message_to_clients(ServerSideNetworkHandler *server_side_network_ server_side_network_handler->displayGameMessage(full_message); is_sending = false; } -// Handle Chat packet Send +// Handle Chat Packet Send void chat_handle_packet_send(const Minecraft *minecraft, ChatPacket *packet) { // Convert To CP-437 packet->message = to_cp437(packet->message); diff --git a/mods/src/input/toggle.cpp b/mods/src/input/toggle.cpp index 7aabd049..08ff4c72 100644 --- a/mods/src/input/toggle.cpp +++ b/mods/src/input/toggle.cpp @@ -49,11 +49,11 @@ static void revert_rotation(Entity *entity) { } } static bool is_front_facing = false; -static LocalPlayer *stored_player = nullptr; +static Entity *stored_player = nullptr; static void GameRenderer_setupCamera_injection(GameRenderer_setupCamera_t original, GameRenderer *game_renderer, const float param_1, const int param_2) { // Get Objects - Minecraft *minecraft = game_renderer->minecraft; - stored_player = minecraft->player; + const Minecraft *minecraft = game_renderer->minecraft; + stored_player = (Entity *) minecraft->camera; // Check If In Third-Person const Options *options = &minecraft->options; @@ -61,7 +61,7 @@ static void GameRenderer_setupCamera_injection(GameRenderer_setupCamera_t origin // Invert Rotation if (is_front_facing) { - invert_rotation((Entity *) stored_player); + invert_rotation(stored_player); } // Call Original Method @@ -69,21 +69,21 @@ static void GameRenderer_setupCamera_injection(GameRenderer_setupCamera_t origin // Revert if (is_front_facing) { - revert_rotation((Entity *) stored_player); + revert_rotation(stored_player); } } static void ParticleEngine_render_injection(ParticleEngine_render_t original, ParticleEngine *particle_engine, Entity *entity, const float param_2) { // Invert Rotation - if (is_front_facing && (Entity *) stored_player == entity) { - invert_rotation((Entity *) stored_player); + if (is_front_facing && stored_player == entity) { + invert_rotation(stored_player); } // Call Original Method original(particle_engine, entity, param_2); // Revert - if (is_front_facing && (Entity *) stored_player == entity) { - revert_rotation((Entity *) stored_player); + if (is_front_facing && stored_player == entity) { + revert_rotation(stored_player); } } diff --git a/mods/src/misc/api.cpp b/mods/src/misc/api.cpp index 839c6997..10633a92 100644 --- a/mods/src/misc/api.cpp +++ b/mods/src/misc/api.cpp @@ -16,7 +16,7 @@ struct Callbacks { std::vector> functions; void run(Args... args) { for (const std::function &func : functions) { - func(args...); + func(std::forward(args)...); } } }; diff --git a/mods/src/misc/graphics.cpp b/mods/src/misc/graphics.cpp index ee83336c..2c352038 100644 --- a/mods/src/misc/graphics.cpp +++ b/mods/src/misc/graphics.cpp @@ -481,7 +481,7 @@ static void Gui_renderProgressIndicator_injection(Gui_renderProgressIndicator_t // Render media_glEnable(GL_BLEND); self->minecraft->textures->blur = true; - self->renderVignette(self->minecraft->player->getBrightness(a), width, height); + self->renderVignette(self->minecraft->camera->getBrightness(a), width, height); self->minecraft->textures->blur = false; media_glDisable(GL_BLEND); // Call Original Method diff --git a/mods/src/misc/ui.cpp b/mods/src/misc/ui.cpp index 8d1fa897..7b84a4a6 100644 --- a/mods/src/misc/ui.cpp +++ b/mods/src/misc/ui.cpp @@ -300,22 +300,24 @@ static void Font_draw_injection(const std::function &orig static void ItemInHandRenderer_renderScreenEffect_injection(__attribute__((unused)) ItemInHandRenderer_renderScreenEffect_t original, ItemInHandRenderer *self, float param_1) { media_glDisable(GL_ALPHA_TEST); const Minecraft *mc = self->minecraft; - LocalPlayer *player = mc->player; - mc->textures->loadAndBindTexture("terrain.png"); - if (player->isInWall()) { - int x = Mth::floor(player->x); - int y = Mth::floor(player->y); - int z = Mth::floor(player->z); - const int id = mc->level->getTile(x, y, z); - Tile *tile = Tile::tiles[id]; - if (tile != nullptr) { - media_glClear(GL_DEPTH_BUFFER_BIT); - self->renderTex(param_1, tile->getTexture1(2)); + Mob *player = mc->camera; + if (player->isPlayer()) { + mc->textures->loadAndBindTexture("terrain.png"); + if (player->isInWall()) { + int x = Mth::floor(player->x); + int y = Mth::floor(player->y); + int z = Mth::floor(player->z); + const int id = mc->level->getTile(x, y, z); + Tile *tile = Tile::tiles[id]; + if (tile != nullptr) { + media_glClear(GL_DEPTH_BUFFER_BIT); + self->renderTex(param_1, tile->getTexture1(2)); + } + } + if (player->isOnFire()) { + media_glClear(GL_DEPTH_BUFFER_BIT); + self->renderFire(param_1); } - } - if (player->isOnFire()) { - media_glClear(GL_DEPTH_BUFFER_BIT); - self->renderFire(param_1); } media_glEnable(GL_ALPHA_TEST); } diff --git a/mods/src/skin/skin.cpp b/mods/src/skin/skin.cpp index 32c14135..71177f57 100644 --- a/mods/src/skin/skin.cpp +++ b/mods/src/skin/skin.cpp @@ -30,11 +30,12 @@ static void Player_username_assign_injection_2(std::string *target, const char * } // Change Texture For HUD -static uint32_t ItemInHandRenderer_render_Textures_loadAndBindTexture_injection(Textures *textures, __attribute__((unused)) std::string const& name) { +static uint32_t ItemInHandRenderer_render_Textures_loadAndBindTexture_injection(Textures *textures, const std::string &name) { // Change Texture - static std::string new_texture; - if (new_texture.length() == 0) { - new_texture = get_skin_texture_path(Strings::default_username); + std::string new_texture = name; + Mob *camera = textures->options->minecraft->camera; + if (camera && camera->isPlayer()) { + new_texture = camera->texture; } // Call Original Method diff --git a/symbols/CMakeLists.txt b/symbols/CMakeLists.txt index 54cf6f1b..ecdab66a 100644 --- a/symbols/CMakeLists.txt +++ b/symbols/CMakeLists.txt @@ -91,6 +91,7 @@ set(SRC src/level/ChunkStorage.def src/level/LightLayer.def src/level/Level.def + src/level/LevelListener.def src/level/renderer/LevelRenderer.def src/level/LevelStorageSource.def src/level/renderer/ParticleEngine.def diff --git a/symbols/src/game/options/Options.def b/symbols/src/game/options/Options.def index 0974b045..6f1b0aca 100644 --- a/symbols/src/game/options/Options.def +++ b/symbols/src/game/options/Options.def @@ -23,4 +23,5 @@ property bool debug = 0xee; property bool server_visible = 0x104; property std::string username = 0x100; property bool invert_mouse = 0xc; -property bool lefty = 0x1a; \ No newline at end of file +property bool lefty = 0x1a; +property Minecraft *minecraft = 0xe4; \ No newline at end of file diff --git a/symbols/src/item/ItemInHandRenderer.def b/symbols/src/item/ItemInHandRenderer.def index c73a0974..c91163d1 100644 --- a/symbols/src/item/ItemInHandRenderer.def +++ b/symbols/src/item/ItemInHandRenderer.def @@ -7,4 +7,5 @@ method void renderItem(Mob *mob, ItemInstance *item) = 0x4b824; method void render(float param_1) = 0x4bfcc; method void renderFire(float param_1) = 0x4ca84; method void renderTex(float param_1, int param_2) = 0x4c7d4; -method void renderScreenEffect(float param_1) = 0x4cc40; \ No newline at end of file +method void renderScreenEffect(float param_1) = 0x4cc40; +method void tick() = 0x4b78c; \ No newline at end of file diff --git a/symbols/src/level/LevelListener.def b/symbols/src/level/LevelListener.def new file mode 100644 index 00000000..2a29a740 --- /dev/null +++ b/symbols/src/level/LevelListener.def @@ -0,0 +1,3 @@ +vtable 0x1068e0; + +virtual-method void entityRemoved(Entity *entity) = 0x38; \ No newline at end of file diff --git a/symbols/src/level/renderer/LevelRenderer.def b/symbols/src/level/renderer/LevelRenderer.def index 3eed29fb..ab79c838 100644 --- a/symbols/src/level/renderer/LevelRenderer.def +++ b/symbols/src/level/renderer/LevelRenderer.def @@ -1,3 +1,5 @@ +extends LevelListener; + vtable 0x107438; constructor (Minecraft *minecraft) = 0x4e5f8; diff --git a/symbols/src/textures/Textures.def b/symbols/src/textures/Textures.def index a051f533..890a347c 100644 --- a/symbols/src/textures/Textures.def +++ b/symbols/src/textures/Textures.def @@ -12,4 +12,5 @@ method Texture *getTemporaryTextureData(uint id) = 0x53168; property bool blur = 0x39; property std::vector dynamic_textures = 0x40; -property uint current_texture = 0x3c; \ No newline at end of file +property uint current_texture = 0x3c; +property Options *options = 0x30; \ No newline at end of file