feat: update spoofer to reflect new data

This commit is contained in:
2026-04-12 12:42:08 -03:00
parent de418a6568
commit 4559b9d4ec
2 changed files with 90 additions and 99 deletions
+86 -94
View File
@@ -56,41 +56,60 @@ void Spoofer::registerListeners(Proxy* proxy)
}); });
} }
#define LOADDATA(fileName, type, camperSet, slasherSet, errorMsg) \
std::string path##type = utils::getExePath() + fileName; \
std::ifstream file##type(path##type); \
if (file##type.is_open()) \
{ \
std::stringstream buff; \
buff << file##type.rdbuf(); \
if (!parseStackable(buff.str(), camperSet, slasherSet)) \
Log::error("Failed to parse {} - {}", fileName, errorMsg); \
else \
Log::verbose("Loaded {} camper ids and {} slasher ids from {}", camperSet.size(), slasherSet.size(), \
fileName); \
} \
else \
Log::warning("Missing {} - {}", fileName, errorMsg);
void Spoofer::loadData() void Spoofer::loadData()
{ {
Log::info("Loading data"); Log::info("Loading data");
std::string catalogPath = utils::getExePath() + "catalog.json"; /*
std::ifstream catalogFile(catalogPath); stackables
if (catalogFile.is_open()) */
static auto loadData = [this](const char* fileName, std::unordered_set<std::string>* camperSet,
std::unordered_set<std::string>* slasherSet,
std::unordered_set<std::string>* globalSet, const char* errorMsg) {
std::ifstream file(utils::getExePath() + fileName);
if (file.is_open())
{
std::stringstream buff;
buff << file.rdbuf();
if (!parseStackable(buff.str(), camperSet, slasherSet, globalSet))
return Log::error("Failed to parse {} - {}", fileName, errorMsg);
else
Log::verbose("Loaded {}", fileName);
}
else
Log::warning("Missing file: {} - {}", fileName, errorMsg);
};
loadData("items.json", &_camperItemIds, 0, 0, "Items wont be added");
loadData("offerings.json", &_camperOfferingIds, &_slasherOfferingIds, &_globalOfferingIds,
"Offerings won't be added");
loadData("addons.json", &_camperAddonIds, &_slasherAddonIds, 0, "Offerings won't be added");
loadData("perks.json", &_camperPerkIds, &_slasherPerkIds, 0, "Offerings won't be added");
/*
catalog items
*/
std::ifstream customizationsFile(utils::getExePath() + "customizations.json");
if (customizationsFile.is_open())
{ {
std::stringstream buff; std::stringstream buff;
buff << catalogFile.rdbuf(); buff << customizationsFile.rdbuf();
if (!parseCatalog(buff.str())) Log::warning("Failed to parse catalog.json - Customizations won't be unlocked"); if (!parseCustomizations(buff.str()))
Log::warning("Failed to parse customizations.json - Outfits and character items won't be added");
else
Log::verbose("Loaded customizations.json");
} }
else
Log::warning("Missing catalog.json - Customizations won't be unlocked");
LOADDATA("items.json", Items, _camperItemIds, _slasherPowerIds, "Items won't be added"); Log::verbose("Finished loading data");
LOADDATA("offerings.json", Offerings, _camperOfferingIds, _slasherOfferingIds, "Offerings won't be added");
LOADDATA("addons.json", Addons, _camperAddonIds, _slasherAddonIds, "Addons won't be added"); Log::verbose("Items - {} camper", _camperItemIds.size());
LOADDATA("perks.json", Perks, _camperPerkIds, _slasherPerkIds, "Perks won't be added"); Log::verbose("Offerings - {} camper | {} slasher | {} global", _camperOfferingIds.size(),
_slasherOfferingIds.size(), _globalOfferingIds.size());
Log::verbose("Addons - {} camper | {} slasher ", _camperAddonIds.size(), _slasherAddonIds.size());
Log::verbose("Perks - {} camper | {} slasher ", _camperPerkIds.size(), _slasherPerkIds.size());
Log::verbose("Catalog - {} outfits | {} items", _catalogOutfitIds.size(), _catalogItemIds.size());
} }
void Spoofer::loadConfig() void Spoofer::loadConfig()
@@ -130,46 +149,8 @@ void Spoofer::loadConfig()
/* /*
data parsing data parsing
*/ */
bool Spoofer::parseCatalog(std::string data) bool Spoofer::parseStackable(std::string data, std::unordered_set<std::string>* camperSet,
{ std::unordered_set<std::string>* slasherSet, std::unordered_set<std::string>* globalSet)
json doc = json::parse(data, nullptr, false);
if (doc.is_discarded())
{
Log::error("Failed to parse catalog");
return false;
}
try
{
const auto& catalogData = doc.at("data");
auto extractIds = [&](const std::string& key, std::unordered_set<std::string>& targetSet) {
if (catalogData.contains(key) && catalogData[key].contains("items"))
for (const auto& id : catalogData[key]["items"])
{
if (id.is_string()) targetSet.insert(id.get<std::string>());
}
else
Log::warning("Catalog missing or invalid category: {}", key);
};
extractIds("item", _catalogItemIds);
extractIds("outfit", _catalogOutfitIds);
}
catch (const json::exception& e)
{
Log::error("Invalid catalog format: {}", e.what());
return false;
}
Log::info("Parsed {} items and {} outfits from catalog", _catalogItemIds.size(), _catalogOutfitIds.size());
return true;
}
bool Spoofer::parseStackable(std::string data, std::unordered_set<std::string>& camperSet,
std::unordered_set<std::string>& slasherSet)
{ {
json doc = json::parse(data, nullptr, false); json doc = json::parse(data, nullptr, false);
if (doc.is_discarded()) if (doc.is_discarded())
@@ -178,18 +159,47 @@ bool Spoofer::parseStackable(std::string data, std::unordered_set<std::string>&
return false; return false;
} }
auto populate = [&](const std::string& key, std::unordered_set<std::string>& targetSet) { auto populate = [&](const std::string& key, std::unordered_set<std::string>* targetSet) {
if (doc.contains(key) && doc[key].is_array()) if (doc.contains(key) && doc[key].is_array())
for (const auto& item : doc[key]) for (const auto& item : doc[key])
{ {
if (item.is_string()) targetSet.insert(item.get<std::string>()); if (item.is_string()) targetSet->insert(item.get<std::string>());
} }
else else
Log::warning("Missing stackables array ({})", key); Log::warning("Missing stackables array ({})", key);
}; };
populate("Slashers", slasherSet); if (camperSet) populate("Campers", camperSet);
populate("Campers", camperSet); if (slasherSet) populate("Slashers", slasherSet);
if (globalSet) populate("All", globalSet);
return true;
}
bool Spoofer::parseCustomizations(std::string data)
{
json doc = json::parse(data, nullptr, false);
if (doc.is_discarded())
{
Log::error("JSON parse error @ parseCustomizations");
return false;
}
if (doc.contains("Items"))
{
for (const auto& item : doc["Items"])
{
if (item.is_string()) _catalogItemIds.insert(item.get<std::string>());
}
}
if (doc.contains("Outfits"))
{
for (const auto& outfit : doc["Outfits"])
{
if (outfit.is_string()) _catalogOutfitIds.insert(outfit.get<std::string>());
}
}
return true; return true;
} }
@@ -200,8 +210,8 @@ bool Spoofer::parseStackable(std::string data, std::unordered_set<std::string>&
std::string Spoofer::getRandomItem() std::string Spoofer::getRandomItem()
{ {
std::vector<const std::unordered_set<std::string>*> allSets = { std::vector<const std::unordered_set<std::string>*> allSets = {
&_camperItemIds, &_slasherPowerIds, &_camperOfferingIds, &_slasherOfferingIds, &_camperItemIds, &_camperOfferingIds, &_slasherOfferingIds, &_camperAddonIds,
&_camperAddonIds, &_slasherAddonIds, &_camperPerkIds, &_slasherPerkIds}; &_slasherAddonIds, &_camperPerkIds, &_slasherPerkIds};
std::vector<const std::unordered_set<std::string>*> validSets; std::vector<const std::unordered_set<std::string>*> validSets;
for (auto* s : allSets) for (auto* s : allSets)
@@ -324,6 +334,7 @@ void Spoofer::modifyCharacterData(json& js)
std::unordered_set<std::string> stackableIds; std::unordered_set<std::string> stackableIds;
stackableIds.insert(_camperItemIds.begin(), _camperItemIds.end()); stackableIds.insert(_camperItemIds.begin(), _camperItemIds.end());
stackableIds.insert(_camperOfferingIds.begin(), _camperOfferingIds.end()); stackableIds.insert(_camperOfferingIds.begin(), _camperOfferingIds.end());
stackableIds.insert(_globalOfferingIds.begin(), _globalOfferingIds.end());
stackableIds.insert(_camperAddonIds.begin(), _camperAddonIds.end()); stackableIds.insert(_camperAddonIds.begin(), _camperAddonIds.end());
stackableIds.insert(_slasherAddonIds.begin(), _slasherAddonIds.end()); stackableIds.insert(_slasherAddonIds.begin(), _slasherAddonIds.end());
stackableIds.insert(_slasherOfferingIds.begin(), _slasherOfferingIds.end()); stackableIds.insert(_slasherOfferingIds.begin(), _slasherOfferingIds.end());
@@ -361,6 +372,8 @@ void Spoofer::modifyCharacterData(json& js)
appendItems(_slasherOfferingIds, false); appendItems(_slasherOfferingIds, false);
appendItems(_slasherPerkIds, true); appendItems(_slasherPerkIds, true);
} }
appendItems(_globalOfferingIds, true);
} }
} }
@@ -372,26 +385,6 @@ void Spoofer::modifyCharacterData(json& js)
/* /*
endpoint handlers endpoint handlers
*/ */
void Spoofer::onGetCatalogItems(std::string& body)
{
std::thread t([body]() {
std::string outPath = utils::getExePath() + "catalog.json";
std::ofstream file(outPath);
if (file.is_open())
{
file << body;
file.close();
Log::verbose("Raw catalog saved to {}", outPath);
}
else
Log::error("Unable to write to catalog.json");
});
t.detach();
parseCatalog(body);
}
void Spoofer::onGetAll(std::string& body) void Spoofer::onGetAll(std::string& body)
{ {
json doc = json::parse(body, nullptr, false); json doc = json::parse(body, nullptr, false);
@@ -624,7 +617,6 @@ void Spoofer::serverResponseHandler(const std::string& url, std::string& body, s
Log::verbose("BHVR api res @ {}", url); Log::verbose("BHVR api res @ {}", url);
#endif #endif
if (url.find("api/v1/extensions/store/getCatalogItems") != std::string::npos) return onGetCatalogItems(body);
if (url.find("api/v1/dbd-character-data/get-all") != std::string::npos) return onGetAll(body); if (url.find("api/v1/dbd-character-data/get-all") != std::string::npos) return onGetAll(body);
if (url.find("api/v1/dbd-character-data/get-all") != std::string::npos) return onGetAll(body); if (url.find("api/v1/dbd-character-data/get-all") != std::string::npos) return onGetAll(body);
if (url.find("api/v1/dbd-inventories/all") != std::string::npos) return onInventoryAll(body); if (url.find("api/v1/dbd-inventories/all") != std::string::npos) return onInventoryAll(body);
+4 -5
View File
@@ -26,9 +26,9 @@ class Spoofer
void loadData(); void loadData();
void loadConfig(); void loadConfig();
bool parseCatalog(std::string data); bool parseStackable(std::string data, std::unordered_set<std::string>* camperSet,
bool parseStackable(std::string data, std::unordered_set<std::string>& camperSet, std::unordered_set<std::string>* slasherSet, std::unordered_set<std::string>* globalSet);
std::unordered_set<std::string>& slasherSet); bool parseCustomizations(std::string data);
std::string getRandomItem(); std::string getRandomItem();
int getRandomQuantity(); int getRandomQuantity();
@@ -36,7 +36,6 @@ class Spoofer
void generateBloodweb(nlohmann::json& data); void generateBloodweb(nlohmann::json& data);
void modifyCharacterData(nlohmann::json& js); void modifyCharacterData(nlohmann::json& js);
void onGetCatalogItems(std::string& body);
void onGetAll(std::string& body); void onGetAll(std::string& body);
void onInventoryAll(std::string& body); void onInventoryAll(std::string& body);
void onMessageList(std::string& body); void onMessageList(std::string& body);
@@ -48,10 +47,10 @@ class Spoofer
SpooferConfig _config; SpooferConfig _config;
std::unordered_set<std::string> _camperItemIds; std::unordered_set<std::string> _camperItemIds;
std::unordered_set<std::string> _slasherPowerIds;
std::unordered_set<std::string> _camperOfferingIds; std::unordered_set<std::string> _camperOfferingIds;
std::unordered_set<std::string> _slasherOfferingIds; std::unordered_set<std::string> _slasherOfferingIds;
std::unordered_set<std::string> _globalOfferingIds;
std::unordered_set<std::string> _camperAddonIds; std::unordered_set<std::string> _camperAddonIds;
std::unordered_set<std::string> _slasherAddonIds; std::unordered_set<std::string> _slasherAddonIds;