2022-09-22 17:43:21 -04:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <string>
|
|
|
|
#include <fstream>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <sstream>
|
2022-09-23 00:31:42 -04:00
|
|
|
#include <unistd.h>
|
2022-09-22 17:43:21 -04:00
|
|
|
|
2024-11-21 22:36:05 -05:00
|
|
|
#include <libreborn/log.h>
|
|
|
|
#include <libreborn/util.h>
|
2022-09-22 17:43:21 -04:00
|
|
|
|
|
|
|
#include "cache.h"
|
2024-11-21 02:16:25 -05:00
|
|
|
#include "configuration.h"
|
2022-09-22 17:43:21 -04:00
|
|
|
|
|
|
|
// Get Cache Path
|
|
|
|
static std::string get_cache_path() {
|
2024-11-21 22:36:05 -05:00
|
|
|
return home_get() + "/.launcher-cache";
|
2022-09-22 17:43:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Load
|
2024-11-24 19:57:52 -05:00
|
|
|
State load_cache() {
|
2022-09-22 17:43:21 -04:00
|
|
|
// Log
|
|
|
|
DEBUG("Loading Launcher Cache...");
|
|
|
|
|
2022-09-25 19:35:51 -04:00
|
|
|
// Return Value
|
2024-11-24 19:57:52 -05:00
|
|
|
State ret;
|
2022-09-25 19:35:51 -04:00
|
|
|
|
2022-09-22 17:43:21 -04:00
|
|
|
// Open File
|
|
|
|
std::ifstream stream(get_cache_path(), std::ios::in | std::ios::binary);
|
|
|
|
if (!stream) {
|
2022-09-25 19:35:51 -04:00
|
|
|
// No Warning If File Doesn't Exist
|
2024-11-24 19:57:52 -05:00
|
|
|
if (errno != ENOENT) {
|
2022-09-22 17:43:21 -04:00
|
|
|
WARN("Unable To Open Launcher Cache For Loading");
|
|
|
|
}
|
2022-09-25 19:35:51 -04:00
|
|
|
} else {
|
2022-09-25 20:56:45 -04:00
|
|
|
// Lock File
|
|
|
|
int lock_fd = lock_file(get_cache_path().c_str());
|
|
|
|
|
2022-09-25 19:35:51 -04:00
|
|
|
// Check Version
|
|
|
|
unsigned char cache_version;
|
|
|
|
stream.read((char *) &cache_version, 1);
|
2024-11-21 02:16:25 -05:00
|
|
|
if (stream.eof()) {
|
|
|
|
// Unable To Read Version
|
|
|
|
WARN("Unable To Read Launcher Cache Version");
|
|
|
|
} else if (cache_version != (unsigned char) CACHE_VERSION) {
|
|
|
|
// Invalid Version
|
|
|
|
WARN("Invalid Launcher Cache Version (Expected: %i, Actual: %i)", CACHE_VERSION, (int) cache_version);
|
2022-09-22 18:08:12 -04:00
|
|
|
} else {
|
2022-09-25 19:35:51 -04:00
|
|
|
// Load Username And Render Distance
|
2024-11-24 19:57:52 -05:00
|
|
|
State state;
|
|
|
|
std::getline(stream, state.username, '\0');
|
|
|
|
std::getline(stream, state.render_distance, '\0');
|
2022-09-25 19:35:51 -04:00
|
|
|
|
|
|
|
// Load Feature Flags
|
2024-11-24 19:57:52 -05:00
|
|
|
std::unordered_map<std::string, bool> flags;
|
2022-09-25 19:35:51 -04:00
|
|
|
std::string flag;
|
|
|
|
while (!stream.eof() && std::getline(stream, flag, '\0')) {
|
2024-11-21 02:16:25 -05:00
|
|
|
if (!flag.empty()) {
|
|
|
|
bool is_enabled = false;
|
|
|
|
stream.read((char *) &is_enabled, sizeof(bool));
|
2024-11-24 19:57:52 -05:00
|
|
|
flags[flag] = is_enabled;
|
2022-09-25 19:35:51 -04:00
|
|
|
}
|
|
|
|
stream.peek();
|
|
|
|
}
|
2024-11-24 19:57:52 -05:00
|
|
|
state.flags.from_cache(flags);
|
2022-09-22 17:43:21 -04:00
|
|
|
|
2024-11-24 19:57:52 -05:00
|
|
|
// Check For Error
|
2022-09-25 19:35:51 -04:00
|
|
|
if (!stream) {
|
|
|
|
WARN("Failure While Loading Launcher Cache");
|
|
|
|
} else {
|
|
|
|
// Success
|
2024-11-24 19:57:52 -05:00
|
|
|
ret = state;
|
2022-09-25 19:35:51 -04:00
|
|
|
}
|
2022-09-22 17:43:21 -04:00
|
|
|
}
|
|
|
|
|
2024-11-21 02:16:25 -05:00
|
|
|
// Close
|
|
|
|
stream.close();
|
|
|
|
|
2022-09-25 20:56:45 -04:00
|
|
|
// Unlock File
|
|
|
|
unlock_file(get_cache_path().c_str(), lock_fd);
|
|
|
|
}
|
2022-09-22 17:43:21 -04:00
|
|
|
|
|
|
|
// Return
|
2022-09-25 19:35:51 -04:00
|
|
|
return ret;
|
2022-09-22 17:43:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Save
|
2024-11-21 02:16:25 -05:00
|
|
|
static void write_env_to_stream(std::ofstream &stream, const std::string &value) {
|
|
|
|
stream.write(value.c_str(), int(value.size()) + 1);
|
|
|
|
}
|
|
|
|
void save_cache(const State &state) {
|
2022-09-22 17:43:21 -04:00
|
|
|
// Log
|
|
|
|
DEBUG("Saving Launcher Cache...");
|
|
|
|
|
|
|
|
// Open File
|
|
|
|
std::ofstream stream(get_cache_path(), std::ios::out | std::ios::binary);
|
|
|
|
if (!stream) {
|
2022-09-25 19:35:51 -04:00
|
|
|
// Fail
|
2022-09-22 17:43:21 -04:00
|
|
|
WARN("Unable To Open Launcher Cache For Saving");
|
2022-09-25 19:35:51 -04:00
|
|
|
} else {
|
2022-09-25 20:56:45 -04:00
|
|
|
// Lock File
|
|
|
|
int lock_fd = lock_file(get_cache_path().c_str());
|
|
|
|
|
2022-09-25 19:35:51 -04:00
|
|
|
// Save Cache Version
|
2024-11-21 02:16:25 -05:00
|
|
|
constexpr unsigned char cache_version = CACHE_VERSION;
|
2022-09-25 19:35:51 -04:00
|
|
|
stream.write((const char *) &cache_version, 1);
|
|
|
|
|
|
|
|
// Save Username And Render Distance
|
2024-11-21 02:16:25 -05:00
|
|
|
write_env_to_stream(stream, state.username);
|
|
|
|
write_env_to_stream(stream, state.render_distance);
|
2022-09-25 19:35:51 -04:00
|
|
|
|
|
|
|
// Save Feature Flags
|
2024-11-21 02:16:25 -05:00
|
|
|
const std::unordered_map<std::string, bool> flags_cache = state.flags.to_cache();
|
|
|
|
for (const std::pair<const std::string, bool> &it : flags_cache) {
|
|
|
|
stream.write(it.first.c_str(), int(it.first.size()) + 1);
|
|
|
|
stream.write((const char *) &it.second, sizeof(bool));
|
2022-09-25 19:35:51 -04:00
|
|
|
}
|
2022-09-22 17:43:21 -04:00
|
|
|
|
2022-09-25 19:35:51 -04:00
|
|
|
// Finish
|
|
|
|
stream.close();
|
2024-11-21 02:16:25 -05:00
|
|
|
if (!stream) {
|
2022-09-25 19:35:51 -04:00
|
|
|
WARN("Failure While Saving Launcher Cache");
|
|
|
|
}
|
|
|
|
|
2022-09-25 20:56:45 -04:00
|
|
|
// Unlock File
|
|
|
|
unlock_file(get_cache_path().c_str(), lock_fd);
|
|
|
|
}
|
2022-09-22 17:43:21 -04:00
|
|
|
}
|
2022-09-23 00:31:42 -04:00
|
|
|
|
|
|
|
// Wipe Cache
|
|
|
|
void wipe_cache() {
|
|
|
|
// Log
|
|
|
|
INFO("Wiping Launcher Cache...");
|
|
|
|
|
|
|
|
// Unlink File
|
2024-06-15 08:52:15 -04:00
|
|
|
const int ret = unlink(get_cache_path().c_str());
|
|
|
|
if (ret != 0 && errno != ENOENT) {
|
2022-09-23 00:31:42 -04:00
|
|
|
WARN("Failure While Wiping Cache: %s", strerror(errno));
|
|
|
|
}
|
|
|
|
}
|