diff --git a/launcher/src/client/available-feature-flags b/launcher/src/client/available-feature-flags index 4d5efe4..4b47304 100644 --- a/launcher/src/client/available-feature-flags +++ b/launcher/src/client/available-feature-flags @@ -44,3 +44,4 @@ FALSE Force EGL TRUE Improved Classic Title Screen FALSE Disable Speed Bridging FALSE Disable Creative Mode Mining Delay +FALSE Add Biome Colors To Grass diff --git a/mods/src/misc/misc.c b/mods/src/misc/misc.c index fc147e8..43e80d5 100644 --- a/mods/src/misc/misc.c +++ b/mods/src/misc/misc.c @@ -332,6 +332,47 @@ HOOK(bind, int, (int sockfd, const struct sockaddr *addr, socklen_t addrlen)) { return (*real_bind)(sockfd, new_addr, addrlen); } +// Change Grass Color +static int32_t get_color(unsigned char *level_source, int32_t x, int32_t z) { + unsigned char *level_source_vtable = *(unsigned char **) level_source; + 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) { + return 0; + } + return *(int32_t *) (biome + Biome_color_property_offset); +} +#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) { + int r_sum = 0; + int g_sum = 0; + int b_sum = 0; + int color_sum = 0; + int x_start = x - (BIOME_BLEND_SIZE / 2); + int z_start = z - (BIOME_BLEND_SIZE / 2); + for (int x_offset = 0; x_offset < BIOME_BLEND_SIZE; x_offset++) { + for (int z_offset = 0; z_offset < BIOME_BLEND_SIZE; z_offset++) { + int32_t color = get_color(level_source, x_start + x_offset, z_start + z_offset); + r_sum += (color >> 16) & 0xff; + g_sum += (color >> 8) & 0xff; + b_sum += color & 0xff; + color_sum++; + } + } + int r_avg = r_sum / color_sum; + int g_avg = g_sum / color_sum; + int b_avg = b_sum / color_sum; + 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) { + int32_t original_color = (*TallGrass_getColor)(tile, level_source, x, y, z); + if (original_color == 0x339933) { + return GrassTile_getColor_injection(tile, level_source, x, y, z); + } else { + return original_color; + } +} + // Init static void nop() { } @@ -437,6 +478,12 @@ void init_misc() { patch((void *) 0x19fa0, nop_patch); } + // Change Grass Color + if (feature_has("Add Biome Colors To Grass", server_disabled)) { + patch_address((void *) GrassTile_getColor_vtable_addr, (void *) GrassTile_getColor_injection); + patch_address((void *) TallGrass_getColor_vtable_addr, (void *) TallGrass_getColor_injection); + } + // Init C++ And Logging _init_misc_cpp(); _init_misc_logging(); diff --git a/symbols/include/symbols/minecraft.h b/symbols/include/symbols/minecraft.h index dec17e3..31ea41f 100644 --- a/symbols/include/symbols/minecraft.h +++ b/symbols/include/symbols/minecraft.h @@ -127,9 +127,21 @@ static uint32_t Tile_setSoundType_vtable_offset = 0xe8; typedef int32_t (*Tile_use_t)(unsigned char *tile, unsigned char *level, int32_t x, int32_t y, int32_t z, unsigned char *player); static uint32_t Tile_use_vtable_offset = 0x98; +typedef int32_t (*Tile_getColor_t)(unsigned char *tile, unsigned char *level_source, int32_t x, int32_t y, int32_t z); +static uint32_t Tile_getColor_vtable_offset = 0xb8; + static uint32_t Tile_id_property_offset = 0x8; // int32_t static uint32_t Tile_category_property_offset = 0x3c; // int32_t +// GrassTile + +static void *GrassTile_getColor_vtable_addr = (void *) 0x111660; + +// TallGrass + +static Tile_getColor_t TallGrass_getColor = (Tile_getColor_t) 0xc25fc; +static void *TallGrass_getColor_vtable_addr = (void *) 0x1121f0; + // TileRenderer typedef void (*TileRenderer_tesselateBlockInWorld_t)(unsigned char *tile_renderer, unsigned char *tile, int32_t x, int32_t y, int32_t z); @@ -506,6 +518,11 @@ static Level_clip_t Level_clip = (Level_clip_t) 0xa3db0; static uint32_t Level_players_property_offset = 0x60; // std::vector +// LevelSource + +typedef unsigned char *(*LevelSource_getBiome_t)(unsigned char *level_source, int32_t x, int32_t z); +static uint32_t LevelSource_getBiome_vtable_offset = 0x24; + // Material typedef bool (*Material_isSolid_t)(unsigned char *material); @@ -861,6 +878,11 @@ static void *PlayerRenderer_render_vtable_addr = (void *) 0x107f08; typedef unsigned char *(*WorkbenchScreen_t)(unsigned char *screen, int32_t param_1); static WorkbenchScreen_t WorkbenchScreen = (WorkbenchScreen_t) 0x301cc; +// Biome + +static uint32_t Biome_color_property_offset = 0x2c; // int32_t +static uint32_t Biome_leaf_color_property_offset = 0x34; // int32_t + // Method That Require C++ Types #ifdef __cplusplus