#include "cache-cleaner.h" #include "win-platform.h" #include #include #include #include #include CacheCleaner::CacheCleaner() : _running(false), _monitorThread(nullptr) { _log = new seallib::Logger("Cache cleaner"); } CacheCleaner::~CacheCleaner() { shutdown(); delete _log; } void CacheCleaner::init() { std::string localAppData = getLocalAppDataPath(); if (localAppData.empty()) { _log->error("Failed to get LocalAppData"); return; } _cacheDir = localAppData + "\\DeadByDaylight\\Saved\\PersistentDownloadDir"; // this is pointless but just in case std::filesystem::create_directories(_cacheDir); clearFolder(_cacheDir); _running = true; _monitorThread = std::make_unique(&CacheCleaner::monitorLoop, this); } void CacheCleaner::shutdown() { _log->verbose("shutting down"); if (!_running) return; _running = false; if (_monitorThread && _monitorThread->joinable()) _monitorThread->join(); _monitorThread.reset(); } std::string CacheCleaner::getLocalAppDataPath() { char buffer[MAX_PATH]; if (SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, buffer) == S_OK) { return std::string(buffer); } return ""; } void CacheCleaner::clearFolder(std::string& path) { try { for (const auto& entry : std::filesystem::directory_iterator(path)) { std::filesystem::remove_all(entry.path()); } } catch (...) { } } void CacheCleaner::monitorLoop() { HANDLE changeHandle = FindFirstChangeNotificationA(_cacheDir.c_str(), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE); if (changeHandle == INVALID_HANDLE_VALUE) { _log->error("Failed to create change notification"); _running = false; return; } _log->verbose("Cache cleaner monitoring started"); std::unordered_set previousPids; while (_running) { for (int i = 0; i < 20 && _running; i++) Sleep(100); if (!_running) break; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) continue; PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); std::unordered_set currentPids; if (Process32First(hSnapshot, &pe32)) { do { DWORD pid = pe32.th32ProcessID; currentPids.insert(pid); if (previousPids.find(pid) == previousPids.end()) { std::string processName(pe32.szExeFile); for (char& c : processName) c = static_cast(tolower(c)); if (processName.find("deadbydaylight") != std::string::npos) { _log->verbose("New DeadByDaylight process detected (PID: {}), clearing cache", pid); clearFolder(_cacheDir); } } } while (Process32Next(hSnapshot, &pe32)); } CloseHandle(hSnapshot); previousPids = std::move(currentPids); } FindCloseChangeNotification(changeHandle); }