From 6249d7ca4d6c5c4d7d36c07374395cb35838c150 Mon Sep 17 00:00:00 2001 From: otavepto <153766569+otavepto@users.noreply.github.com> Date: Sat, 20 Jan 2024 17:50:16 +0200 Subject: [PATCH] * attempt to auto detect mods with the same behavior as if they were defined in mods.json, for an easier config * new function in local storage to get list of folders at root level, given some path * use last week epoch as the default time for mods dates (created, added, etc...) * UGC: some params checks according to SDK docs for CreateQueryXXX() functions * fixed some mistakes --- build_win.bat | 2 +- dll/dll/local_storage.h | 1 + dll/dll/steam_ugc.h | 46 ++++-- dll/local_storage.cpp | 31 ++++ dll/settings_parser.cpp | 312 +++++++++++++++++++++---------------- helpers/common_helpers.cpp | 2 +- helpers/dbg_log.cpp | 2 +- 7 files changed, 246 insertions(+), 150 deletions(-) diff --git a/build_win.bat b/build_win.bat index 67e45ee8..375e7931 100644 --- a/build_win.bat +++ b/build_win.bat @@ -479,7 +479,7 @@ echo: & echo: if %last_code% equ 0 ( echo // copying readmes + files examples xcopy /y /s /e /r "post_build\steam_settings.EXAMPLE\" "%build_root_dir%\steam_settings.EXAMPLE\" - xcopy /y /s /e /r "post_build\win\ColdClientLoader.EXAMPLE\" "%steamclient_dir%\EXAMPLE\" + xcopy /y /s /e /r "post_build\win\ColdClientLoader.EXAMPLE\" "%steamclient_dir%\dll_injection.EXAMPLE\" copy /y "%tools_src_dir%\steamclient_loader\win\ColdClientLoader.ini" "%steamclient_dir%\" copy /y "post_build\README.release.md" "%build_root_dir%\" copy /y "CHANGELOG.md" "%build_root_dir%\" diff --git a/dll/dll/local_storage.h b/dll/dll/local_storage.h index c5094ca0..6ae146e2 100644 --- a/dll/dll/local_storage.h +++ b/dll/dll/local_storage.h @@ -64,6 +64,7 @@ public: void setAppId(uint32 appid); static int store_file_data(std::string folder, std::string file, char *data, unsigned int length); static std::vector get_filenames_path(std::string path); + static std::vector get_folders_path(std::string path); int store_data(std::string folder, std::string file, char *data, unsigned int length); int store_data_settings(std::string file, char *data, unsigned int length); diff --git a/dll/dll/steam_ugc.h b/dll/dll/steam_ugc.h index 5ee44b63..f1885768 100644 --- a/dll/dll/steam_ugc.h +++ b/dll/dll/steam_ugc.h @@ -171,7 +171,14 @@ Steam_UGC(class Settings *settings, class Ugc_Remote_Storage_Bridge *ugc_bridge, UGCQueryHandle_t CreateQueryUserUGCRequest( AccountID_t unAccountID, EUserUGCList eListType, EUGCMatchingUGCType eMatchingUGCType, EUserUGCListSortOrder eSortOrder, AppId_t nCreatorAppID, AppId_t nConsumerAppID, uint32 unPage ) { PRINT_DEBUG("Steam_UGC::CreateQueryUserUGCRequest %u %i %i %i %u %u %u\n", unAccountID, eListType, eMatchingUGCType, eSortOrder, nCreatorAppID, nConsumerAppID, unPage); - //TODO + std::lock_guard lock(global_mutex); + + if (nCreatorAppID != settings->get_local_game_id().AppID() || nConsumerAppID != settings->get_local_game_id().AppID()) return k_UGCQueryHandleInvalid; + if (unPage < 1) return k_UGCQueryHandleInvalid; + if (eListType < 0) return k_UGCQueryHandleInvalid; + if (unAccountID != settings->get_local_steam_id().GetAccountID()) return k_UGCQueryHandleInvalid; + + // TODO return new_ugc_query(eListType == k_EUserUGCList_Subscribed || eListType == k_EUserUGCList_Published); } @@ -180,7 +187,13 @@ UGCQueryHandle_t CreateQueryUserUGCRequest( AccountID_t unAccountID, EUserUGCLis UGCQueryHandle_t CreateQueryAllUGCRequest( EUGCQuery eQueryType, EUGCMatchingUGCType eMatchingeMatchingUGCTypeFileType, AppId_t nCreatorAppID, AppId_t nConsumerAppID, uint32 unPage ) { PRINT_DEBUG("Steam_UGC::CreateQueryAllUGCRequest\n"); - //TODO + std::lock_guard lock(global_mutex); + + if (nCreatorAppID != settings->get_local_game_id().AppID() || nConsumerAppID != settings->get_local_game_id().AppID()) return k_UGCQueryHandleInvalid; + if (unPage < 1) return k_UGCQueryHandleInvalid; + if (eQueryType < 0) return k_UGCQueryHandleInvalid; + + // TODO return new_ugc_query(); } @@ -188,7 +201,12 @@ UGCQueryHandle_t CreateQueryAllUGCRequest( EUGCQuery eQueryType, EUGCMatchingUGC UGCQueryHandle_t CreateQueryAllUGCRequest( EUGCQuery eQueryType, EUGCMatchingUGCType eMatchingeMatchingUGCTypeFileType, AppId_t nCreatorAppID, AppId_t nConsumerAppID, const char *pchCursor = NULL ) { PRINT_DEBUG("Steam_UGC::CreateQueryAllUGCRequest other\n"); - //TODO + std::lock_guard lock(global_mutex); + + if (nCreatorAppID != settings->get_local_game_id().AppID() || nConsumerAppID != settings->get_local_game_id().AppID()) return k_UGCQueryHandleInvalid; + if (eQueryType < 0) return k_UGCQueryHandleInvalid; + + // TODO return new_ugc_query(); } @@ -196,6 +214,12 @@ UGCQueryHandle_t CreateQueryAllUGCRequest( EUGCQuery eQueryType, EUGCMatchingUGC UGCQueryHandle_t CreateQueryUGCDetailsRequest( PublishedFileId_t *pvecPublishedFileID, uint32 unNumPublishedFileIDs ) { PRINT_DEBUG("Steam_UGC::CreateQueryUGCDetailsRequest\n"); + std::lock_guard lock(global_mutex); + + if (!pvecPublishedFileID) return k_UGCQueryHandleInvalid; + if (unNumPublishedFileIDs < 1) return k_UGCQueryHandleInvalid; + + // TODO std::set only(pvecPublishedFileID, pvecPublishedFileID + unNumPublishedFileIDs); return new_ugc_query(false, only); } @@ -248,10 +272,7 @@ bool GetQueryUGCResult( UGCQueryHandle_t handle, uint32 index, SteamUGCDetails_t { PRINT_DEBUG("Steam_UGC::GetQueryUGCResult %llu %u %p\n", handle, index, pDetails); std::lock_guard lock(global_mutex); - if (pDetails) { - memset(pDetails, 0, sizeof(SteamUGCDetails_t)); - pDetails->m_eResult = k_EResultFail; - } + if (handle == k_UGCQueryHandleInvalid) return false; auto request = std::find_if(ugc_queries.begin(), ugc_queries.end(), [&handle](struct UGC_query const& item) { return item.handle == handle; }); if (ugc_queries.end() == request) { @@ -262,6 +283,11 @@ bool GetQueryUGCResult( UGCQueryHandle_t handle, uint32 index, SteamUGCDetails_t return false; } + if (pDetails) { + memset(pDetails, 0, sizeof(SteamUGCDetails_t)); + pDetails->m_eResult = k_EResultFail; + } + auto it = request->results.begin(); std::advance(it, index); PublishedFileId_t file_id = *it; @@ -530,8 +556,10 @@ bool SetReturnLongDescription( UGCQueryHandle_t handle, bool bReturnLongDescript bool SetReturnMetadata( UGCQueryHandle_t handle, bool bReturnMetadata ) { - PRINT_DEBUG("TODO Steam_UGC::SetReturnMetadata\n"); + PRINT_DEBUG("TODO Steam_UGC::SetReturnMetadata %i\n", (int)bReturnMetadata); std::lock_guard lock(global_mutex); + + if (handle == k_UGCQueryHandleInvalid) return false; return true; } @@ -1086,7 +1114,7 @@ bool GetItemInstallInfo( PublishedFileId_t nPublishedFileID, uint64 *punSizeOnDi if (punTimeStamp) *punTimeStamp = mod.timeUpdated; if (pchFolder && cchFolderSize) { PRINT_DEBUG(" mod path: '%s'\n", mod.path.c_str()); - memset(pchFolder, cchFolderSize, 0); + memset(pchFolder, 0, cchFolderSize); mod.path.copy(pchFolder, cchFolderSize - 1); } diff --git a/dll/local_storage.cpp b/dll/local_storage.cpp index 5aff27b1..3e2b9b70 100644 --- a/dll/local_storage.cpp +++ b/dll/local_storage.cpp @@ -159,6 +159,11 @@ std::vector Local_Storage::get_filenames_path(std::string path) return std::vector(); } +std::vector Local_Storage::get_folders_path(std::string path) +{ + return std::vector(); +} + std::vector Local_Storage::load_image(std::string const& image_path) { return std::vector(); @@ -185,6 +190,7 @@ std::string Local_Storage::desanitize_string(std::string name) } #else + #if defined(__WINDOWS__) static BOOL DirectoryExists(LPCWSTR szPath) @@ -559,6 +565,7 @@ std::string Local_Storage::get_global_settings_path() std::vector Local_Storage::get_filenames_path(std::string path) { + if (path.empty()) return {}; if (path.back() != *PATH_SEPARATOR) { path.append(PATH_SEPARATOR); } @@ -569,6 +576,30 @@ std::vector Local_Storage::get_filenames_path(std::string path) return output; } +std::vector Local_Storage::get_folders_path(std::string path) +{ + if (path.empty()) return {}; + if (path.back() != *PATH_SEPARATOR) { + path.append(PATH_SEPARATOR); + } + + std::vector output{}; + try + { + const auto path_p = std::filesystem::path(path); + if (!std::filesystem::is_directory(path_p)) return output; + + for (const auto &dir_entry : + std::filesystem::directory_iterator(path_p, std::filesystem::directory_options::follow_directory_symlink)) { + if (std::filesystem::is_directory(dir_entry)) { + output.push_back(dir_entry.path().filename().u8string()); + } + } + } catch(...) { } + + return output; +} + int Local_Storage::store_data(std::string folder, std::string file, char *data, unsigned int length) { if (folder.size() && folder.back() != *PATH_SEPARATOR) { diff --git a/dll/settings_parser.cpp b/dll/settings_parser.cpp index 842ebed0..24a399f5 100644 --- a/dll/settings_parser.cpp +++ b/dll/settings_parser.cpp @@ -777,151 +777,187 @@ static void parse_force_branch_name(class Settings *settings_client, Settings *s } // steam_settings/mods +static const auto one_week_ago_epoch = std::chrono::duration_cast( + ( startup_time - std::chrono::hours(24 * 7) ).time_since_epoch() +).count(); + +static size_t get_file_size_safe(const std::string &filepath, const std::string &basepath, int32 default_val = 0) +{ + try + { + const auto file_p = common_helpers::to_absolute(filepath, basepath); + if (file_p.empty()) return default_val; + + size_t size = 0; + if (common_helpers::file_size(file_p, size)) { + return size; + } + } catch(...) {} + return default_val; +} + +static std::string get_mod_preview_url(const std::string &previewFileName, const std::string &mod_id) +{ + if (previewFileName.empty()) { + return std::string(); + } else { + auto settings_folder = std::string(Local_Storage::get_game_settings_path()); + std::replace(settings_folder.begin(), settings_folder.end(), '\\', '/'); + return "file://" + settings_folder + "mod_images/" + mod_id + "/" + previewFileName; + } + +} + +static void try_parse_mods_file(class Settings *settings_client, Settings *settings_server, nlohmann::json &mod_items, const std::string &mods_folder) +{ + + for (auto mod = mod_items.begin(); mod != mod_items.end(); ++mod) { + try { + std::string mod_images_fullpath = Local_Storage::get_game_settings_path() + "mod_images" + PATH_SEPARATOR + std::string(mod.key()); + Mod_entry newMod; + newMod.id = std::stoull(mod.key()); + newMod.title = mod.value().value("title", std::string(mod.key())); + + // make sure this is never empty + newMod.path = mod.value().value("path", std::string("")); + if (newMod.path.empty()) { + newMod.path = mods_folder + PATH_SEPARATOR + std::string(mod.key()); + } + + newMod.fileType = k_EWorkshopFileTypeCommunity; + newMod.description = mod.value().value("description", std::string("")); + newMod.steamIDOwner = mod.value().value("steam_id_owner", settings_client->get_local_steam_id().ConvertToUint64()); + newMod.timeCreated = mod.value().value("time_created", (uint32)one_week_ago_epoch); + newMod.timeUpdated = mod.value().value("time_updated", (uint32)one_week_ago_epoch); + newMod.timeAddedToUserList = mod.value().value("time_added", (uint32)one_week_ago_epoch); + newMod.visibility = k_ERemoteStoragePublishedFileVisibilityPublic; + newMod.banned = false; + newMod.acceptedForUse = true; + newMod.tagsTruncated = false; + newMod.tags = mod.value().value("tags", std::string("")); + + newMod.primaryFileName = mod.value().value("primary_filename", std::string("")); + int32 primary_filesize = 0; + if (!newMod.primaryFileName.empty()) { + primary_filesize = (int32)get_file_size_safe(newMod.primaryFileName, newMod.path, primary_filesize); + } + newMod.primaryFileSize = mod.value().value("primary_filesize", primary_filesize); + + newMod.previewFileName = mod.value().value("preview_filename", std::string("")); + int32 preview_filesize = 0; + if (!newMod.previewFileName.empty()) { + preview_filesize = (int32)get_file_size_safe(newMod.previewFileName, mod_images_fullpath, preview_filesize); + } + newMod.previewFileSize = mod.value().value("preview_filesize", preview_filesize); + + newMod.workshopItemURL = mod.value().value("workshop_item_url", "https://steamcommunity.com/sharedfiles/filedetails/?id=" + std::string(mod.key())); + newMod.votesUp = mod.value().value("upvotes", (uint32)500); + newMod.votesDown = mod.value().value("downvotes", (uint32)12); + + float score = 0.97f; + try + { + score = newMod.votesUp / (float)(newMod.votesUp + newMod.votesDown); + } catch(...) {} + newMod.score = mod.value().value("score", score); + + newMod.numChildren = mod.value().value("num_children", (uint32)0); + newMod.previewURL = mod.value().value("preview_url", get_mod_preview_url(newMod.previewFileName, std::string(mod.key()))); + + settings_client->addMod(newMod.id, newMod.title, newMod.path); + settings_server->addMod(newMod.id, newMod.title, newMod.path); + settings_client->addModDetails(newMod.id, newMod); + settings_server->addModDetails(newMod.id, newMod); + + PRINT_DEBUG(" parsed mod '%s':\n", std::string(mod.key()).c_str()); + PRINT_DEBUG(" path (will be used for primary file): '%s'\n", newMod.path.c_str()); + PRINT_DEBUG(" images path (will be used for preview file): '%s'\n", mod_images_fullpath.c_str()); + PRINT_DEBUG(" primary_filename: '%s'\n", newMod.primaryFileName.c_str()); + PRINT_DEBUG(" primary_filesize: %i bytes\n", newMod.primaryFileSize); + PRINT_DEBUG(" primary file handle: %llu\n", settings_client->getMod(newMod.id).handleFile); + PRINT_DEBUG(" preview_filename: '%s'\n", newMod.previewFileName.c_str()); + PRINT_DEBUG(" preview_filesize: %i bytes\n", newMod.previewFileSize); + PRINT_DEBUG(" preview file handle: %llu\n", settings_client->getMod(newMod.id).handlePreviewFile); + PRINT_DEBUG(" workshop_item_url: '%s'\n", newMod.workshopItemURL.c_str()); + PRINT_DEBUG(" preview_url: '%s'\n", newMod.previewURL.c_str()); + } catch (std::exception& e) { + PRINT_DEBUG("MODLOADER ERROR: %s\n", e.what()); + } + } +} + +// called if mods.json doesn't exist or invalid +static void try_detect_mods_folder(class Settings *settings_client, Settings *settings_server, const std::string &mods_folder) +{ + std::vector all_mods = Local_Storage::get_folders_path(mods_folder); + for (auto & mod_folder: all_mods) { + std::string mod_images_fullpath = Local_Storage::get_game_settings_path() + "mod_images" + PATH_SEPARATOR + mod_folder; + try { + Mod_entry newMod; + newMod.id = std::stoull(mod_folder); + newMod.title = mod_folder; + + // make sure this is never empty + newMod.path = mods_folder + PATH_SEPARATOR + mod_folder; + + newMod.fileType = k_EWorkshopFileTypeCommunity; + newMod.description = "mod #" + mod_folder; + newMod.steamIDOwner = settings_client->get_local_steam_id().ConvertToUint64(); + newMod.timeCreated = (uint32)one_week_ago_epoch; + newMod.timeUpdated = (uint32)one_week_ago_epoch; + newMod.timeAddedToUserList = (uint32)one_week_ago_epoch; + newMod.visibility = k_ERemoteStoragePublishedFileVisibilityPublic; + newMod.banned = false; + newMod.acceptedForUse = true; + newMod.tagsTruncated = false; + newMod.tags = ""; + + std::vector mod_primary_files = Local_Storage::get_filenames_path(newMod.path); + newMod.primaryFileName = mod_primary_files.size() ? mod_primary_files[0] : ""; + newMod.primaryFileSize = (int32)get_file_size_safe(newMod.primaryFileName, newMod.path); + + std::vector mod_preview_files = Local_Storage::get_filenames_path(mod_images_fullpath); + newMod.previewFileName = mod_preview_files.size() ? mod_preview_files[0] : ""; + newMod.previewFileSize = (int32)get_file_size_safe(newMod.previewFileName, mod_images_fullpath); + + newMod.workshopItemURL = "https://steamcommunity.com/sharedfiles/filedetails/?id=" + mod_folder; + newMod.votesUp = (uint32)500; + newMod.votesDown = (uint32)12; + newMod.score = 0.97f; + newMod.numChildren = (uint32)0; + newMod.previewURL = get_mod_preview_url(newMod.previewFileName, mod_folder); + + settings_client->addMod(newMod.id, newMod.title, newMod.path); + settings_server->addMod(newMod.id, newMod.title, newMod.path); + settings_client->addModDetails(newMod.id, newMod); + settings_server->addModDetails(newMod.id, newMod); + PRINT_DEBUG(" detected mod '%s':\n", mod_folder.c_str()); + PRINT_DEBUG(" path (will be used for primary file): '%s'\n", newMod.path.c_str()); + PRINT_DEBUG(" images path (will be used for preview file): '%s'\n", mod_images_fullpath.c_str()); + PRINT_DEBUG(" primary_filename: '%s'\n", newMod.primaryFileName.c_str()); + PRINT_DEBUG(" primary_filesize: %i bytes\n", newMod.primaryFileSize); + PRINT_DEBUG(" primary file handle: %llu\n", settings_client->getMod(newMod.id).handleFile); + PRINT_DEBUG(" preview_filename: '%s'\n", newMod.previewFileName.c_str()); + PRINT_DEBUG(" preview_filesize: %i bytes\n", newMod.previewFileSize); + PRINT_DEBUG(" preview file handle: %llu\n", settings_client->getMod(newMod.id).handlePreviewFile); + PRINT_DEBUG(" workshop_item_url: '%s'\n", newMod.workshopItemURL.c_str()); + PRINT_DEBUG(" preview_url: '%s'\n", newMod.previewURL.c_str()); + } catch (...) {} + } +} + static void parse_mods_folder(class Settings *settings_client, Settings *settings_server, class Local_Storage *local_storage) { - std::chrono::system_clock::time_point one_week_ago = std::chrono::system_clock::now() - std::chrono::hours(24 * 7); - auto one_week_ago_epoch = std::chrono::duration_cast(one_week_ago.time_since_epoch()).count(); - std::string mod_path = Local_Storage::get_game_settings_path() + "mods"; + std::string mods_folder = Local_Storage::get_game_settings_path() + "mods"; nlohmann::json mod_items = nlohmann::json::object(); static constexpr auto mods_json_file = "mods.json"; std::string mods_json_path = Local_Storage::get_game_settings_path() + mods_json_file; if (local_storage->load_json(mods_json_path, mod_items)) { - for (auto mod = mod_items.begin(); mod != mod_items.end(); ++mod) { - try { - std::string mod_images_folder = Local_Storage::get_game_settings_path() + "mod_images" + PATH_SEPARATOR + std::string(mod.key()); - Mod_entry newMod; - newMod.id = std::stoull(mod.key()); - newMod.title = mod.value().value("title", std::string(mod.key())); - newMod.path = mod.value().value("path", std::string("")); - if (newMod.path.empty()) { - newMod.path = mod_path + PATH_SEPARATOR + std::string(mod.key()); - } - newMod.fileType = k_EWorkshopFileTypeCommunity; - newMod.description = mod.value().value("description", std::string("")); - newMod.steamIDOwner = mod.value().value("steam_id_owner", settings_client->get_local_steam_id().ConvertToUint64()); - newMod.timeCreated = mod.value().value("time_created", (uint32)std::chrono::system_clock::now().time_since_epoch().count()); - newMod.timeUpdated = mod.value().value("time_updated", (uint32)one_week_ago.time_since_epoch().count()); - newMod.timeAddedToUserList = mod.value().value("time_added", (uint32)one_week_ago_epoch); - newMod.visibility = k_ERemoteStoragePublishedFileVisibilityPublic; - newMod.banned = false; - newMod.acceptedForUse = true; - newMod.tagsTruncated = false; - newMod.tags = mod.value().value("tags", std::string("")); - - constexpr static auto get_file_size = []( - const std::string &filepath, - const std::string &basepath, - int32 default_val = 0) -> size_t { - try - { - const auto file_p = common_helpers::to_absolute(filepath, basepath); - if (file_p.empty()) return default_val; - - size_t size = 0; - if (common_helpers::file_size(file_p, size)) { - return size; - } - } catch(...) {} - return default_val; - }; - - newMod.primaryFileName = mod.value().value("primary_filename", std::string("")); - int32 primary_filesize = 0; - if (!newMod.primaryFileName.empty()) { - primary_filesize = (int32)get_file_size(newMod.primaryFileName, newMod.path, primary_filesize); - } - newMod.primaryFileSize = mod.value().value("primary_filesize", primary_filesize); - - newMod.previewFileName = mod.value().value("preview_filename", std::string("")); - int32 preview_filesize = 0; - if (!newMod.previewFileName.empty()) { - preview_filesize = (int32)get_file_size( - newMod.previewFileName, - mod_images_folder, - preview_filesize); - } - newMod.previewFileSize = mod.value().value("preview_filesize", preview_filesize); - - newMod.workshopItemURL = mod.value().value("workshop_item_url", "https://steamcommunity.com/sharedfiles/filedetails/?id=" + std::string(mod.key())); - newMod.votesUp = mod.value().value("upvotes", (uint32)1); - newMod.votesDown = mod.value().value("downvotes", (uint32)0); - - float score = 1.0f; - try - { - score = newMod.votesUp / (float)(newMod.votesUp + newMod.votesDown); - } catch(...) {} - newMod.score = mod.value().value("score", score); - - newMod.numChildren = mod.value().value("num_children", (uint32)0); - - newMod.previewURL = mod.value().value("preview_url", std::string("")); - if (newMod.previewURL.empty()) { - if (newMod.previewFileName.empty()) { - newMod.previewURL = std::string(); - } else { - auto settings_folder = std::string(Local_Storage::get_game_settings_path()); - std::replace(settings_folder.begin(), settings_folder.end(), '\\', '/'); - newMod.previewURL = "file://" + settings_folder + "mod_images/" + std::string(mod.key()) + "/" + newMod.previewFileName; - } - } - - settings_client->addMod(newMod.id, newMod.title, newMod.path); - settings_server->addMod(newMod.id, newMod.title, newMod.path); - settings_client->addModDetails(newMod.id, newMod); - settings_server->addModDetails(newMod.id, newMod); - - PRINT_DEBUG(" parsed mod '%s':\n", std::string(mod.key()).c_str()); - PRINT_DEBUG(" path (will be used for primary file): '%s'\n", newMod.path.c_str()); - PRINT_DEBUG(" images path (will be used for preview file): '%s'\n", mod_images_folder.c_str()); - PRINT_DEBUG(" primary_filename: '%s'\n", newMod.primaryFileName.c_str()); - PRINT_DEBUG(" primary_filesize: %i bytes\n", newMod.primaryFileSize); - PRINT_DEBUG(" primary file handle: %llu\n", settings_client->getMod(newMod.id).handleFile); - PRINT_DEBUG(" preview_filename: '%s'\n", newMod.previewFileName.c_str()); - PRINT_DEBUG(" preview_filesize: %i bytes\n", newMod.previewFileSize); - PRINT_DEBUG(" preview file handle: %llu\n", settings_client->getMod(newMod.id).handlePreviewFile); - PRINT_DEBUG(" workshop_item_url: '%s'\n", newMod.workshopItemURL.c_str()); - PRINT_DEBUG(" preview_url: '%s'\n", newMod.previewURL.c_str()); - } catch (std::exception& e) { - PRINT_DEBUG("MODLOADER ERROR: %s\n", e.what()); - } - } + PRINT_DEBUG("Attempting to parse mods.json\n"); + try_parse_mods_file(settings_client, settings_server, mod_items, mods_folder); } else { // invalid mods.json or doesn't exist - std::vector paths = Local_Storage::get_filenames_path(mod_path); - for (auto & p: paths) { - PRINT_DEBUG("mod directory %s\n", p.c_str()); - try { - Mod_entry newMod; - newMod.id = std::stoull(p); - newMod.title = p; - newMod.path = mod_path + PATH_SEPARATOR + p; - newMod.fileType = k_EWorkshopFileTypeCommunity; - newMod.description = ""; - newMod.steamIDOwner = (uint64)0; - newMod.timeCreated = (uint32)one_week_ago_epoch; - newMod.timeUpdated = (uint32)one_week_ago_epoch; - newMod.timeAddedToUserList = (uint32)one_week_ago_epoch; - newMod.visibility = k_ERemoteStoragePublishedFileVisibilityPublic; - newMod.banned = false; - newMod.acceptedForUse = true; - newMod.tagsTruncated = false; - newMod.tags = ""; - newMod.primaryFileName = ""; - newMod.primaryFileSize = (int32)0; - newMod.previewFileName = ""; - newMod.previewFileSize = (int32)0; - newMod.workshopItemURL = ""; - newMod.votesUp = (uint32)1; - newMod.votesDown = (uint32)0; - newMod.score = 1.0f; - newMod.numChildren = (uint32)0; - newMod.previewURL = ""; - settings_client->addMod(newMod.id, newMod.title, newMod.path); - settings_server->addMod(newMod.id, newMod.title, newMod.path); - settings_client->addModDetails(newMod.id, newMod); - settings_server->addModDetails(newMod.id, newMod); - } catch (...) {} - } + PRINT_DEBUG("Failed to load mods.json, attempting to auto detect mods folder\n"); + try_detect_mods_folder(settings_client, settings_server, mods_folder); } } diff --git a/helpers/common_helpers.cpp b/helpers/common_helpers.cpp index b802c03b..59002f98 100644 --- a/helpers/common_helpers.cpp +++ b/helpers/common_helpers.cpp @@ -134,7 +134,7 @@ std::wstring common_helpers::to_upper(std::wstring wstr) return _wstr; } -std::filesystem::path to_absolute_impl(const std::filesystem::path &path, const std::filesystem::path &base) +static std::filesystem::path to_absolute_impl(const std::filesystem::path &path, const std::filesystem::path &base) { if (path.is_absolute()) { return path; diff --git a/helpers/dbg_log.cpp b/helpers/dbg_log.cpp index fe4a0e81..2e6bf12b 100644 --- a/helpers/dbg_log.cpp +++ b/helpers/dbg_log.cpp @@ -15,7 +15,7 @@ static std::recursive_mutex f_mtx{}; bool dbg_log::init(const wchar_t *path) { - auto p = std::filesystem::path(path).string(); + auto p = std::filesystem::path(path).u8string(); return init(p.c_str()); }