diff --git a/src/app/hook/hook.cpp b/src/app/hook/hook.cpp index 414e4b9..43fc9b0 100644 --- a/src/app/hook/hook.cpp +++ b/src/app/hook/hook.cpp @@ -22,9 +22,9 @@ bool hook::load(process_t proc) for (const std::string& dll : hook::dlls) { #ifdef _M_AMD64 - std::string dll_path = fs::get_cur_dir().append(logger::va("\\x86_64\\%s", &dll[0])); + std::string dll_path = fs::get_cur_dir().append(logger::va("x86_64\\%s", &dll[0])); #else - std::string dll_path = fs::get_cur_dir().append(logger::va("\\x86\\%s", &dll[0])); + std::string dll_path = fs::get_cur_dir().append(logger::va("x86\\%s", &dll[0])); #endif logger::log_debug(logger::va("Loading %s", &dll_path[0])); @@ -61,7 +61,10 @@ bool hook::load(process_t proc) BringWindowToTop(proc.hwnd); SetForegroundWindow(proc.hwnd); SetFocus(proc.hwnd); + //Set to top most temporarily SetWindowPos(proc.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + //Set back + SetWindowPos(proc.hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); ShowWindow(proc.hwnd, SW_NORMAL); return true; diff --git a/src/app/hook/impl/d3d10_impl.cpp b/src/app/hook/impl/d3d10_impl.cpp index 47d9fec..0ec3e28 100644 --- a/src/app/hook/impl/d3d10_impl.cpp +++ b/src/app/hook/impl/d3d10_impl.cpp @@ -24,7 +24,8 @@ long __stdcall hkPresent10(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT F audio::init_overlay(hwnd); input::init_overlay(hwnd); - ImGui::CreateContext(); + menus::init(); + ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX10_Init(device); diff --git a/src/app/hook/impl/d3d11_impl.cpp b/src/app/hook/impl/d3d11_impl.cpp index 1034368..edc23ce 100644 --- a/src/app/hook/impl/d3d11_impl.cpp +++ b/src/app/hook/impl/d3d11_impl.cpp @@ -27,7 +27,8 @@ long __stdcall hkPresent11(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT F audio::init_overlay(hwnd); input::init_overlay(hwnd); - ImGui::CreateContext(); + menus::init(); + ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX11_Init(device, context); diff --git a/src/app/hook/impl/d3d9_impl.cpp b/src/app/hook/impl/d3d9_impl.cpp index e092676..0455fbe 100644 --- a/src/app/hook/impl/d3d9_impl.cpp +++ b/src/app/hook/impl/d3d9_impl.cpp @@ -33,7 +33,8 @@ long __stdcall hkEndScene(LPDIRECT3DDEVICE9 pDevice) audio::init_overlay(hwnd); input::init_overlay(hwnd); - ImGui::CreateContext(); + menus::init(); + ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX9_Init(pDevice); diff --git a/src/app/hook/impl/opengl3_impl.cpp b/src/app/hook/impl/opengl3_impl.cpp index f569a3b..27d24fe 100644 --- a/src/app/hook/impl/opengl3_impl.cpp +++ b/src/app/hook/impl/opengl3_impl.cpp @@ -18,7 +18,8 @@ BOOL __stdcall hwglSwapBuffers(_In_ HDC hDc) audio::init_overlay(hwnd); input::init_overlay(hwnd); - ImGui::CreateContext(); + menus::init(); + ImGui_ImplWin32_Init(hwnd); ImGui_ImplOpenGL3_Init(); diff --git a/src/app/main.cpp b/src/app/main.cpp index bfde990..9349aec 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -5,6 +5,7 @@ #include "menus/menus.hpp" #include "audio/audio.hpp" #include "settings/settings.hpp" +#include "fs/fs.hpp" #ifndef OVERLAY #include "window/window.hpp" @@ -28,6 +29,7 @@ void init_app() #endif #endif + fs::init(); settings::init(); global::desired_framerate = 60; diff --git a/src/app/menus/menus.cpp b/src/app/menus/menus.cpp index 71ea5de..8844025 100644 --- a/src/app/menus/menus.cpp +++ b/src/app/menus/menus.cpp @@ -5,6 +5,7 @@ #include "api/api.hpp" #include "audio/audio.hpp" #include "hook/hook.hpp" +#include "settings/settings.hpp" #ifndef OVERLAY #include "gfx/gfx.hpp" @@ -15,21 +16,25 @@ #include #endif -#ifndef OVERLAY + void menus::init() { IMGUI_CHECKVERSION(); ImGui::CreateContext(); + ImGui::GetIO().IniFilename = nullptr; + menus::build_font(ImGui::GetIO()); +#ifndef OVERLAY ImGui_ImplSDL2_InitForSDLRenderer(global::window, global::renderer); ImGui_ImplSDLRenderer_Init(global::renderer); -} #endif +} void menus::update() { + #ifndef OVERLAY if (menus::show_snow) { @@ -46,8 +51,21 @@ void menus::update() menus::snow = {}; } } + + static float count = 0; + count += 1.0f * global::get_timestep(); + if (count > 100.0f) + { + count = 0.0f; + if (hook::auto_refresh) + { + hook::get_procs(); + } + } #endif + settings::update(); + #ifdef OVERLAY if (!global::hide) { @@ -299,9 +317,34 @@ void menus::places() if (ImGui::Button("Reset Filter")) { menus::filtering = false; + menus::current_country = "N/A"; memset(menus::search_buffer, 0, sizeof(menus::search_buffer)); } + if (ImGui::BeginCombo("Country", &menus::current_country[0])) + { + if (api::places_done) + { + if (ImGui::Button("Reset ##country")) + { + menus::current_country = "N/A"; + } + + ImGui::NewLine(); + + for (std::string c : api::all_countries) + { + if (ImGui::Button(&c[0])) + { + menus::current_country = c; + + ImGui::CloseCurrentPopup(); + } + } + } + ImGui::EndCombo(); + } + if (ImGui::InputText("Search", menus::search_buffer, sizeof(search_buffer))) { menus::filtering = true; @@ -349,10 +392,21 @@ void menus::places() for (auto place : api::places) { - if (ImGui::Button(&logger::va("[%s] %s", &place.country[0], &place.city[0])[0])) + if (!menus::current_country.compare("N/A")) { - api::get_details(place); - ImGui::CloseCurrentPopup(); + if (ImGui::Button(&logger::va("[%s] %s", &place.country[0], &place.city[0])[0])) + { + api::get_details(place); + ImGui::CloseCurrentPopup(); + } + } + else if (!menus::current_country.compare(place.country)) + { + if (ImGui::Button(&logger::va("%s", &place.city[0])[0])) + { + api::get_details(place); + ImGui::CloseCurrentPopup(); + } } } } @@ -365,13 +419,25 @@ void menus::places() ImGui::Text("No results found with the search term\n%s", menus::search_buffer); ImGui::Text("Tip: Search filters country, city, and place ID; case sensitive"); } + else { for (auto place : api::filtered_places) { - if (ImGui::Button(&logger::va("[%s] %s", &place.country[0], &place.city[0])[0])) + if (!menus::current_country.compare("N/A")) { - api::get_details(place); - ImGui::CloseCurrentPopup(); + if (ImGui::Button(&logger::va("[%s] %s", &place.country[0], &place.city[0])[0])) + { + api::get_details(place); + ImGui::CloseCurrentPopup(); + } + } + else if (!menus::current_country.compare(place.country)) + { + if (ImGui::Button(&logger::va("%s", &place.city[0])[0])) + { + api::get_details(place); + ImGui::CloseCurrentPopup(); + } } } } @@ -423,6 +489,7 @@ void menus::stations() if (!has) { api::favorite_stations.emplace_back(station); + settings::add_favorite(station); } } } @@ -452,6 +519,21 @@ void menus::favorites() audio::currently_playing.region.country = station.place.country; audio::play(station.id); } + + ImGui::SameLine(); + + if (ImGui::Button(&logger::va("-##%s", &station.id[0])[0])) + { + for (int i = 0; i < api::favorite_stations.size(); i++) + { + if (api::favorite_stations[i].id == station.id) + { + settings::remove_favorite(station); + api::favorite_stations.erase(api::favorite_stations.begin() + i); + break; + } + } + } } } ImGui::EndMenu(); @@ -482,6 +564,13 @@ void menus::overlay() { hook::get_procs(); } + + ImGui::SameLine(); + + if (ImGui::Button(&logger::va("Auto Refresh [%s]", &logger::get_toggle(hook::auto_refresh)[0])[0])) + { + hook::auto_refresh = !hook::auto_refresh; + } ImGui::NewLine(); @@ -543,9 +632,9 @@ void menus::enumerate_snow() void menus::build_font(ImGuiIO& io) { - std::string font = fs::get_cur_dir().append("/fonts/NotoSans-Regular.ttf"); - std::string font_jp = fs::get_cur_dir().append("/fonts/NotoSansJP-Regular.ttf"); - std::string emoji = fs::get_cur_dir().append("/fonts/NotoEmoji-Regular.ttf"); + std::string font = fs::get_pref_dir().append("fonts/NotoSans-Regular.ttf"); + std::string font_jp = fs::get_pref_dir().append("fonts/NotoSansJP-Regular.ttf"); + std::string emoji = fs::get_pref_dir().append("fonts/NotoEmoji-Regular.ttf"); if (fs::exists(font)) { @@ -583,3 +672,4 @@ bool menus::show_drpc; bool menus::filtering = false; char menus::search_buffer[64]; +std::string menus::current_country = "N/A"; \ No newline at end of file diff --git a/src/app/menus/menus.hpp b/src/app/menus/menus.hpp index 0c1ea11..9959f66 100644 --- a/src/app/menus/menus.hpp +++ b/src/app/menus/menus.hpp @@ -5,10 +5,10 @@ class menus { public: + static void init(); static void update(); #ifndef OVERLAY - static void init(); static void prepare(); static void present(); static void cleanup(); @@ -21,6 +21,7 @@ class menus static bool show_drpc; static char search_buffer[64]; + static std::string current_country; static std::string currently_playing; diff --git a/src/app/settings/settings.cpp b/src/app/settings/settings.cpp index 65554b7..04e5ac0 100644 --- a/src/app/settings/settings.cpp +++ b/src/app/settings/settings.cpp @@ -1,4 +1,3 @@ -#include "global.hpp" #include "logger/logger.hpp" #include "fs/fs.hpp" @@ -14,7 +13,7 @@ void settings::init() void settings::update() { - if(fs::exists(settings::config_file)) settings::config = ini_load(settings::config_file); + if(fs::exists(settings::config_file)) settings::config = ini_load(&settings::config_file[0]); else if (!fs::exists(settings::config_file)) { const char* ini_default = @@ -27,7 +26,7 @@ void settings::update() settings::config = ini_create(ini_default, strlen(ini_default)); - ini_save(settings::config, settings::config_file); + ini_save(settings::config, &settings::config_file[0]); } menus::show_drpc = settings::get_boolean(ini_get(settings::config, "startup", "Discord")); @@ -43,6 +42,94 @@ void settings::update() } ini_free(settings::config); + + + if (!fs::exists(settings::favorites_file)) + { + fs::write(settings::favorites_file, "", false); + } + + std::string fav_contents = fs::read(settings::favorites_file); + std::vector stations = logger::split(fs::read(settings::favorites_file), '|'); + + if (stations.size() > 0) + { + api::favorite_stations = {}; + + for (std::string station : stations) + { + std::vector temp = logger::split(station, ','); + + if (temp.size() == 5) + { + station_t s; + + s.title = temp[0]; + + s.place.country = temp[1]; + s.place.city = temp[2]; + s.place.id = temp[3]; + + s.id = temp[4]; + + api::favorite_stations.emplace_back(s); + } + } + } +} + +void settings::add_favorite(station_t station) +{ + std::string contents; + + contents.append(station.title); + contents.append(","); + + contents.append(station.place.country); + contents.append(","); + contents.append(station.place.city); + contents.append(","); + contents.append(station.place.id); + contents.append(","); + + contents.append(station.id); + + contents.append("|"); + + logger::va("%s", &contents[0]); + + fs::write(settings::favorites_file, contents, true); +} + +void settings::remove_favorite(station_t station) +{ + std::string contents = fs::read(settings::favorites_file); + + int index = -1; + std::vector stations = logger::split(contents, '|'); + for (int i = 0; i < stations.size(); i++) + { + std::string id = logger::split(stations[i], ',')[4]; + if (!station.id.compare(id)) + { + index = i; + break; + } + } + + if (index != -1) + { + stations.erase(stations.begin() + index); + } + + contents.clear(); + + for (std::string s : stations) + { + contents.append(s); + } + + fs::write(settings::favorites_file, contents, false); } bool settings::get_boolean(const char* bool_text) @@ -51,6 +138,6 @@ bool settings::get_boolean(const char* bool_text) else return false; } -const char* settings::config_file = "config.ini"; -const char* settings::favorites_file = "stations.fav"; +std::string settings::config_file = logger::va("%s%s", &fs::get_pref_dir()[0], "config.ini"); +std::string settings::favorites_file = logger::va("%s%s", &fs::get_pref_dir()[0], "stations.fav");; ini_t* settings::config; diff --git a/src/app/settings/settings.hpp b/src/app/settings/settings.hpp index 85fe3fc..c44b494 100644 --- a/src/app/settings/settings.hpp +++ b/src/app/settings/settings.hpp @@ -2,15 +2,19 @@ #include +#include "api/api.hpp" + class settings { public: static void init(); static void update(); static bool get_boolean(const char* bool_text); + static void add_favorite(station_t station); + static void remove_favorite(station_t station); private: - static const char* config_file; - static const char* favorites_file; + static std::string config_file; + static std::string favorites_file; static ini_t* config; }; \ No newline at end of file diff --git a/src/helper/main.cpp b/src/helper/main.cpp index da74243..0d74d60 100644 --- a/src/helper/main.cpp +++ b/src/helper/main.cpp @@ -62,9 +62,15 @@ void load() exit(0); } + //Not sure one does the trick but they all sound nice BringWindowToTop(proc.hwnd); SetForegroundWindow(proc.hwnd); SetFocus(proc.hwnd); + //Set to top most temporarily + SetWindowPos(proc.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + //Set back + SetWindowPos(proc.hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + ShowWindow(proc.hwnd, SW_NORMAL); } int __stdcall WinMain(HINSTANCE instance, HINSTANCE prev_instance, char* cmd_line, int cmd_show) diff --git a/src/utils/fs/fs.hpp b/src/utils/fs/fs.hpp index bdb8016..73ecff3 100644 --- a/src/utils/fs/fs.hpp +++ b/src/utils/fs/fs.hpp @@ -5,11 +5,22 @@ #endif #include +#include #include class fs { public: + //Copies important files to the pref directory + static void init() + { + if (fs::exists("fonts")) + { + fs::move(fs::get_cur_dir().append("fonts"), fs::get_pref_dir().append("fonts")); + fs::del("fonts"); + } + } + static bool exists(const std::string& path) { return std::filesystem::exists(path); @@ -17,18 +28,61 @@ class fs static std::string get_cur_dir() { - return std::filesystem::current_path().string(); + return std::filesystem::current_path().string() + "\\"; } - static void write(const std::string& path, const std::string& contents) + static std::string get_pref_dir() { #ifndef HELPER - std::string full_path = logger::va("%s/%s", SDL_GetPrefPath("BttrDrgn", "radio.garten"), path); -#else - std::string full_path = path; + return std::string(SDL_GetPrefPath("BttrDrgn", "radio.garten")); #endif - std::ofstream ofs(full_path); - ofs << contents; - ofs.close(); + return ""; + } + + static void write(const std::string& path, const std::string& contents, const bool append) + { + std::ofstream stream(path, std::ios::binary | std::ofstream::out | (append ? std::ofstream::app : 0)); + + if (stream.is_open()) + { + stream.write(contents.data(), static_cast(contents.size())); + stream.close(); + } + } + + static std::string read(const std::string& path) + { + std::ifstream in(path); + std::ostringstream out; + out << in.rdbuf(); + return out.str(); + } + + static void del(const std::string& path) + { + std::filesystem::remove(path); + } + + static void move(const std::string& path, const std::string& new_path, bool create_root = true) + { + if (create_root) + { + std::filesystem::create_directory(new_path); + } + + for (std::filesystem::path p : std::filesystem::directory_iterator(path)) + { + std::filesystem::path dest = new_path / p.filename(); + + if (std::filesystem::is_directory(p)) + { + std::filesystem::create_directory(dest); + move(p.string().c_str(), dest.string().c_str(), false); + } + else + { + std::filesystem::rename(p, dest); + } + } } }; \ No newline at end of file diff --git a/src/utils/logger/logger.hpp b/src/utils/logger/logger.hpp index 7c7a0b7..5b0e4a4 100644 --- a/src/utils/logger/logger.hpp +++ b/src/utils/logger/logger.hpp @@ -62,19 +62,23 @@ class logger } } - static std::vector split(std::string string, const std::string& delimiter) + static std::vector split(const std::string& s, char seperator) { - std::vector out = std::vector(); - std::uint32_t pos = 0u; + std::vector output; - while ((pos = string.find(delimiter)) != std::string::npos) + std::string::size_type prev_pos = 0, pos = 0; + + while ((pos = s.find(seperator, pos)) != std::string::npos) { - out.emplace_back(string.substr(0, pos)); - string.erase(0, pos + delimiter.size()); + std::string substring(s.substr(prev_pos, pos - prev_pos)); + + output.push_back(substring); + + prev_pos = ++pos; } - out.emplace_back(string); + output.push_back(s.substr(prev_pos, pos - prev_pos)); // Last word - return out; + return output; } }; \ No newline at end of file