diff --git a/Overlay.cpp b/Overlay.cpp index 71db5b6..bc648e7 100644 --- a/Overlay.cpp +++ b/Overlay.cpp @@ -210,31 +210,52 @@ void renderAllTextures(MPI::PlayerInfoTextures &textures, int height, bool hasEr renderText(textures.level, width, height); width += 5 * screenWidth * statsFontRatio; - if (textures.stars.singleColor) { - renderText(textures.stars.single, width, height); - // render the star symbol - int starsTextureW, starsTextureH; - SDL_QueryTexture(textures.stars.single.get(), NULL, NULL, &starsTextureW, &starsTextureH); - renderText(textures.stars.symbol, width + starsTextureW, height); + if (FL::config.mode == FL::Mode::BEDWARS) { + if (textures.stars.singleColor) { + renderText(textures.stars.single, width, height); + // render the star symbol + int starsTextureW, starsTextureH; + SDL_QueryTexture(textures.stars.single.get(), NULL, NULL, &starsTextureW, &starsTextureH); + renderText(textures.stars.symbol, width + starsTextureW, height); + + } else { + int starsTextureXPos = renderMultiTexts(textures.stars.multi, width, height); + // render the star symbol + renderText(textures.stars.symbol, starsTextureXPos, height); + } - } else { - int starsTextureXPos = renderMultiTexts(textures.stars.multi, width, height); - // render the star symbol - renderText(textures.stars.symbol, starsTextureXPos, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.FK, width, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.FD, width, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.FKDR, width, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.W, width, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.L, width, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.WLR, width, height); + + } else if (FL::config.mode == FL::Mode::MINI_WALLS) { + //renderText(textures.kit, width, height); + //width += 5 * screenWidth * statsFontRatio; + renderText(textures.K, width, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.D, width, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.KDR, width, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.FK, width, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.W, width, height); + width += 5 * screenWidth * statsFontRatio; + //renderText(textures.witherKills, width, height); + //width += 5 * screenWidth * statsFontRatio; + renderText(textures.witherDamage, width, height); + width += 5 * screenWidth * statsFontRatio; + renderText(textures.arrowsShot, width, height); } - - width += 5 * screenWidth * statsFontRatio; - renderText(textures.FK, width, height); - width += 5 * screenWidth * statsFontRatio; - renderText(textures.FD, width, height); - width += 5 * screenWidth * statsFontRatio; - renderText(textures.FKDR, width, height); - width += 5 * screenWidth * statsFontRatio; - renderText(textures.W, width, height); - width += 5 * screenWidth * statsFontRatio; - renderText(textures.L, width, height); - width += 5 * screenWidth * statsFontRatio; - renderText(textures.WLR, width, height); } } @@ -261,7 +282,7 @@ int main(int argc, char *args[]) { SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG); SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest"); // linear causes the player heads to become blurry - // SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); + //SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) { spdlog::critical("Error initializing SDL. Error: {}", SDL_GetError()); @@ -362,7 +383,8 @@ int main(int argc, char *args[]) { // Create the centered title text SDL2::Texture titleTextTexture; { - SDL2::Surface titleTextSurface(TTF_RenderText_Blended(titleFont.get(), "Stats Overlay (Ctrl+Shift+O)", {255, 255, 255, 255})); + std::string windowTitle = "Stats Overlay (Ctrl+Shift+O) - " + FL::modeToString(FL::config.mode); + SDL2::Surface titleTextSurface(TTF_RenderText_Blended(titleFont.get(), windowTitle.c_str(), {255, 255, 255, 255})); titleTextTexture.reset(SDL_CreateTextureFromSurface(renderer.get(), titleTextSurface.get())); int titleTextWidth, titleTextHeight; SDL_QueryTexture(titleTextTexture.get(), NULL, NULL, &titleTextWidth, &titleTextHeight); @@ -408,12 +430,21 @@ int main(int argc, char *args[]) { createTextTexture(dummyTextInfo.level, "Level", statsFont); createTextTexture(dummyTextInfo.stars.single, "Stars", statsFont); createTextTexture(dummyTextInfo.stars.symbol, "", symbolsFont); + createTextTexture(dummyTextInfo.K, "K", statsFont); + createTextTexture(dummyTextInfo.D, "D", statsFont); + createTextTexture(dummyTextInfo.KDR, "KDR", statsFont); createTextTexture(dummyTextInfo.FK, "FK", statsFont); createTextTexture(dummyTextInfo.FD, "FD", statsFont); createTextTexture(dummyTextInfo.FKDR, "FKDR", statsFont); createTextTexture(dummyTextInfo.W, "W", statsFont); createTextTexture(dummyTextInfo.L, "L", statsFont); createTextTexture(dummyTextInfo.WLR, "WLR", statsFont); + createTextTexture(dummyTextInfo.kit, "Kit", statsFont); + createTextTexture(dummyTextInfo.witherKills, "WK", statsFont); + createTextTexture(dummyTextInfo.witherDamage, "WD", statsFont); + createTextTexture(dummyTextInfo.arrowsShot, "AS", statsFont); + createTextTexture(dummyTextInfo.arrowsHit, "AH", statsFont); + createTextTexture(dummyTextInfo.AHP, "AHP", statsFont); } spdlog::info("Raising overlay GUI"); @@ -568,48 +599,68 @@ int main(int argc, char *args[]) { } else if (player.bedwars.errorMessage.size() > 0) { errorMessage = player.bedwars.errorMessage; + + } else if (player.miniWalls.errorMessage.size() > 0) { + errorMessage = player.miniWalls.errorMessage; } if (errorMessage.size() == 0) { - BWI::info stats; - - if (FL::config.displayMode == "solos") { - stats = player.bedwars.solos; - - } else if (FL::config.displayMode == "doubles") { - stats = player.bedwars.doubles; - - } else if (FL::config.displayMode == "threes") { - stats = player.bedwars.threes; - - } else if (FL::config.displayMode == "fours") { - stats = player.bedwars.fours; - - } else { - stats = player.bedwars.overall; - } - if (!player.textures.init) { player.textures.init = true; createHeadTexture(player.textures.skin, player.skin); createTextTexture(player.textures.username, player.username, statsFont); createTextTexture(player.textures.level, std::to_string(player.networkLevel), statsFont); - if (!player.bedwars.hasMultiStarColor) { - createTextTexture(player.textures.stars.single, std::to_string(player.bedwars.stars), statsFont, player.bedwars.starColor); - - } else { - player.textures.stars.singleColor = false; - createMultiColorTextTexture(player.textures.stars.multi, std::to_string(player.bedwars.stars), statsFont, player.bedwars.starColors); + if (FL::config.mode == FL::Mode::BEDWARS) { + BWI::info stats; + + if (FL::config.displayMode == "bw_solos") { + stats = player.bedwars.solos; + + } else if (FL::config.displayMode == "bw_doubles") { + stats = player.bedwars.doubles; + + } else if (FL::config.displayMode == "bw_threes") { + stats = player.bedwars.threes; + + } else if (FL::config.displayMode == "bw_fours") { + stats = player.bedwars.fours; + + } else { + stats = player.bedwars.overall; + } + + if (!player.bedwars.hasMultiStarColor) { + createTextTexture(player.textures.stars.single, std::to_string(player.bedwars.stars), statsFont, player.bedwars.starColor); + + } else { + player.textures.stars.singleColor = false; + createMultiColorTextTexture(player.textures.stars.multi, std::to_string(player.bedwars.stars), statsFont, player.bedwars.starColors); + } + + createTextTexture(player.textures.stars.symbol, player.bedwars.starSymbol, symbolsFont, player.bedwars.starSymbolColor); + createTextTexture(player.textures.FK, std::to_string(stats.FK), statsFont); + createTextTexture(player.textures.FD, std::to_string(stats.FD), statsFont); + createTextTexture(player.textures.FKDR, to2DPString(stats.FKDR), statsFont); + createTextTexture(player.textures.W, std::to_string(stats.W), statsFont); + createTextTexture(player.textures.L, std::to_string(stats.L), statsFont); + createTextTexture(player.textures.WLR, to2DPString(stats.WLR), statsFont); + + } else if (FL::config.mode == FL::Mode::MINI_WALLS) { + MWI::info stats = player.miniWalls.overall; + + createTextTexture(player.textures.kit, stats.activeKit, statsFont); + createTextTexture(player.textures.K, std::to_string(stats.K), statsFont); + createTextTexture(player.textures.D, std::to_string(stats.D), statsFont); + createTextTexture(player.textures.KDR, to2DPString(stats.KDR), statsFont); + createTextTexture(player.textures.FK, std::to_string(stats.FK), statsFont); + createTextTexture(player.textures.W, std::to_string(stats.W), statsFont); + createTextTexture(player.textures.witherKills, std::to_string(stats.witherKills), statsFont); + createTextTexture(player.textures.witherDamage, std::to_string(stats.witherDamage), statsFont); + createTextTexture(player.textures.arrowsShot, std::to_string(stats.arrowsShot), statsFont); + createTextTexture(player.textures.arrowsHit, std::to_string(stats.arrowsHit), statsFont); + createTextTexture(player.textures.AHP, std::to_string(stats.AHP), statsFont); } - - createTextTexture(player.textures.stars.symbol, player.bedwars.starSymbol, symbolsFont, player.bedwars.starSymbolColor); - createTextTexture(player.textures.FK, std::to_string(stats.FK), statsFont); - createTextTexture(player.textures.FD, std::to_string(stats.FD), statsFont); - createTextTexture(player.textures.FKDR, to2DPString(stats.FKDR), statsFont); - createTextTexture(player.textures.W, std::to_string(stats.W), statsFont); - createTextTexture(player.textures.L, std::to_string(stats.L), statsFont); - createTextTexture(player.textures.WLR, to2DPString(stats.WLR), statsFont); } renderAllTextures(player.textures, currentHeight, false); diff --git a/include/File_Loader.h b/include/File_Loader.h index c8fa6d7..b6564ce 100644 --- a/include/File_Loader.h +++ b/include/File_Loader.h @@ -59,7 +59,7 @@ namespace FL { "// renderHeadOverlay: render extra head/face details (true/false)\n" "// fakeFullscreen: fake fullscreen support (true/false)\n" "// apiKey: Hypixel API key (/api new)\n" - "// displayMode: mode to display (solos/doubles/threes/fours/overall)\n" + "// displayMode: mode to display (bw_solos/bw_doubles/bw_threes/bw_fours/bw_overall/miniwalls)\n" "// titleFontPath: location of font for the title bar\n" "// statsFontPath: location of font for the player stats\n" "// minecraftLogPath: location of Minecraft's log path\n"; @@ -71,12 +71,29 @@ namespace FL { return ss.str(); } + enum class Mode { + BEDWARS, + MINI_WALLS + }; + + inline std::string modeToString(Mode mode) { + switch (mode) { + case Mode::BEDWARS: + return "BedWars"; + case Mode::MINI_WALLS: + return "Mini Walls"; + default: + return "???"; + } + } + struct Data { int screenWidth = 800, opacity = 70, scale = 100, fileDelay = 100, cachePlayerTime = 4 * 60; bool renderHeadOverlay = true, fakeFullscreen = true; SDL_Color backgroundColor = {50, 50, 50, 255}; - std::string apiKey = "your-hypixel-api-key-here", displayMode = "overall", minecraftLogPath = "C:/Users/YourName/AppData/Roaming/.minecraft/logs/latest.log", + std::string apiKey = "YOUR-HYPIXEL-API-KEY-HERE", displayMode = "bw_overall", minecraftLogPath = "C:/Users/YourName/AppData/Roaming/.minecraft/logs/latest.log", titleFontPath = "./assets/SourceCodePro.ttf", statsFontPath = "./assets/SourceCodePro.ttf"; + Mode mode = Mode::BEDWARS; }; Data config; @@ -257,14 +274,25 @@ namespace FL { try { std::string displayMode = data.at("displayMode"); - if (displayMode == "overall" || displayMode == "solos" || displayMode == "doubles" || displayMode == "threes" || displayMode == "fours") { - config.displayMode = "overall"; + std::transform(displayMode.begin(), displayMode.end(), displayMode.begin(), [](char &c) { + return std::tolower(c); + }); + + if (displayMode == "bw_overall" || displayMode == "bw_solos" || displayMode == "bw_doubles" || displayMode == "bw_threes" || displayMode == "bw_fours" || displayMode == "miniwalls") { + config.displayMode = displayMode; spdlog::info("Set displayMode={}", config.displayMode); } else { spdlog::info("Invalid displayMode"); } + if (config.displayMode.rfind("bw_", 0) == 0) { // starts with bw_ + config.mode = Mode::BEDWARS; + + } else if (config.displayMode == "miniwalls") { + config.mode = Mode::MINI_WALLS; + } + } catch (const JSON::json::out_of_range &e) { spdlog::warn("Could not load displayMode"); } diff --git a/include/Mini_Walls.h b/include/Mini_Walls.h new file mode 100644 index 0000000..f9e5a1d --- /dev/null +++ b/include/Mini_Walls.h @@ -0,0 +1,147 @@ +/* +MIT License + +Copyright (c) 2022 sbplat + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#pragma once + +#include "Types.h" + +#include +#include + +#include +#include + + +#ifndef MINI_WALLS_H +#define MINI_WALLS_H + +namespace MWI { + + namespace JSON = nlohmann; + + struct info { + std::string activeKit; + int K = 0, D = 0, FK = 0, W = 0, witherKills = 0, witherDamage = 0, + arrowsShot = 0, arrowsHit = 0; + float KDR = 0, AHP = 0; + + void round2DP() { + KDR = std::floor(KDR * 100) / 100.0; + AHP = std::floor(AHP * 100) / 100.0; // Arrow hit percentage + } + }; + + struct MiniWallsInfo { + std::string username, errorMessage; + JSON::json stats; + + MWI::info overall; + + void init() { + if (stats.empty()) { + return; + } + + updateOverall(); + + spdlog::debug("Initialized Mini Walls data for player={}", username); + } + + void updateStats(MWI::info &mode, std::string id) { + try { + mode.activeKit = stats.at(id + "miniwalls_activeKit"); + + } catch (const JSON::json::out_of_range &e) { + } + + if (mode.activeKit.empty()) { + mode.activeKit = "X"; + + } else { + mode.activeKit = std::toupper(mode.activeKit.front()); + } + + try { + mode.K = stats.at(id + "kills_mini_walls"); + + } catch (const JSON::json::out_of_range &e) { + } + + try { + mode.D = stats.at(id + "deaths_mini_walls"); + + } catch (const JSON::json::out_of_range &e) { + } + + mode.KDR = mode.K / (float)(mode.D == 0 ? 1 : mode.D); + + try { + mode.FK = stats.at(id + "final_kills_mini_walls"); + + } catch (const JSON::json::out_of_range &e) { + } + + try { + mode.W = stats.at(id + "wins_mini_walls"); + + } catch (const JSON::json::out_of_range &e) { + } + + try { + mode.witherKills = stats.at(id + "wither_kills_mini_walls"); + + } catch (const JSON::json::out_of_range &e) { + } + + try { + mode.witherDamage = stats.at(id + "wither_damage_mini_walls"); + + } catch (const JSON::json::out_of_range &e) { + } + + try { + mode.arrowsShot = stats.at(id + "arrows_shot_mini_walls"); + + } catch (const JSON::json::out_of_range &e) { + } + + try { + mode.arrowsHit = stats.at(id + "arrows_hit_mini_walls"); + + } catch (const JSON::json::out_of_range &e) { + } + + mode.AHP = mode.arrowsHit / (float)(mode.arrowsShot == 0 ? 1 : mode.arrowsShot); + + mode.round2DP(); + } + + void updateOverall() { + updateStats(overall, ""); + } + }; + +} // namespace MWI + +#endif // MINI_WALLS_H diff --git a/include/Player.h b/include/Player.h index 7995308..ec5c657 100644 --- a/include/Player.h +++ b/include/Player.h @@ -25,6 +25,7 @@ SOFTWARE. #pragma once #include "Bedwars.h" +#include "Mini_Walls.h" #include "Types.h" #include @@ -118,7 +119,11 @@ namespace MPI { struct PlayerInfoTextures { bool init = false; SDL2::Texture skin, username, level, - FK, FD, FKDR, W, L, WLR, + K, D, KDR, + FK, FD, FKDR, + W, L, WLR, + kit, witherKills, witherDamage, + arrowsShot, arrowsHit, AHP, errorMessage; StarTextures stars; }; @@ -134,6 +139,7 @@ namespace MPI { int networkLevel = 1; BWI::BedWarsInfo bedwars; + MWI::MiniWallsInfo miniWalls; PlayerInfoTextures textures; @@ -370,6 +376,7 @@ namespace MPI { calculateLevel(); initBedwarsInfo(); + initMiniWallsInfo(); spdlog::debug("Done updating Hypixel data for player={}", username); @@ -468,6 +475,21 @@ namespace MPI { bedwars.init(); } + + void initMiniWallsInfo() { + spdlog::debug("Initializing Mini Walls info for player={}", username); + + miniWalls.username = username; + + try { + miniWalls.stats = data.at("player").at("stats").at("Arcade"); + + } catch (const JSON::json::out_of_range &e) { + spdlog::debug("No Arcade (mini walls) data available for player={}", username); + } + + miniWalls.init(); + } }; } // namespace MPI