aboutsummaryrefslogtreecommitdiff
path: root/primedev
diff options
context:
space:
mode:
authorRémy Raes <raes.remy@gmail.com>2024-07-06 12:40:36 +0200
committerGitHub <noreply@github.com>2024-07-06 12:40:36 +0200
commit497945bbbd18b4ff9cd264dc6a9d6cf8ba6bf08e (patch)
tree14c2aace20c8356fa2b64f4cb4a641aba40ebcba /primedev
parent3edcc91c72c96c33f8eae76a7078f78126bbea28 (diff)
downloadNorthstarLauncher-497945bbbd18b4ff9cd264dc6a9d6cf8ba6bf08e.tar.gz
NorthstarLauncher-497945bbbd18b4ff9cd264dc6a9d6cf8ba6bf08e.zip
Fix multiple audio file overrides (#677)v1.26.3-rc1v1.26.2v1.26.1-rc5v1.26.1-rc4v1.26.1
This basically prevents audio files from being loaded into memory if matching audio event has already been overriden by a previous mod, preventing a crash from occurring. This means that audio mods now respect the load priority, i.e. mods with higher priority (= lower int value) will have priority over other mods on audio overrides.
Diffstat (limited to 'primedev')
-rw-r--r--primedev/client/audio.cpp31
-rw-r--r--primedev/client/audio.h4
-rw-r--r--primedev/mods/modmanager.cpp2
3 files changed, 31 insertions, 6 deletions
diff --git a/primedev/client/audio.cpp b/primedev/client/audio.cpp
index 099fdcee..e5989f5c 100644
--- a/primedev/client/audio.cpp
+++ b/primedev/client/audio.cpp
@@ -7,6 +7,7 @@
#include <iostream>
#include <sstream>
#include <random>
+#include <ranges>
AUTOHOOK_INIT()
@@ -28,7 +29,7 @@ unsigned char EMPTY_WAVE[45] = {0x52, 0x49, 0x46, 0x46, 0x25, 0x00, 0x00, 0x00,
0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x88, 0x58,
0x01, 0x00, 0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00};
-EventOverrideData::EventOverrideData(const std::string& data, const fs::path& path)
+EventOverrideData::EventOverrideData(const std::string& data, const fs::path& path, const std::vector<std::string>& registeredEvents)
{
if (data.length() <= 0)
{
@@ -191,6 +192,14 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
{
std::string pathString = file.path().string();
+ // Retrieve event id from path (standard?)
+ std::string eventId = file.path().parent_path().filename().string();
+ if (std::find(registeredEvents.begin(), registeredEvents.end(), eventId) != registeredEvents.end())
+ {
+ spdlog::warn("{} couldn't be loaded because {} event has already been overrided, skipping.", pathString, eventId);
+ continue;
+ }
+
// Open the file.
std::ifstream wavStream(pathString, std::ios::binary);
@@ -259,7 +268,7 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
LoadedSuccessfully = true;
}
-bool CustomAudioManager::TryLoadAudioOverride(const fs::path& defPath)
+bool CustomAudioManager::TryLoadAudioOverride(const fs::path& defPath, std::string modName)
{
if (IsDedicatedServer())
return true; // silently fail
@@ -279,19 +288,35 @@ bool CustomAudioManager::TryLoadAudioOverride(const fs::path& defPath)
jsonStream.close();
- std::shared_ptr<EventOverrideData> data = std::make_shared<EventOverrideData>(jsonStringStream.str(), defPath);
+ // Pass the list of overriden events to avoid multiple event registrations crash
+ auto kv = std::views::keys(m_loadedAudioOverrides);
+ std::vector<std::string> keys {kv.begin(), kv.end()};
+ std::shared_ptr<EventOverrideData> data = std::make_shared<EventOverrideData>(jsonStringStream.str(), defPath, keys);
if (!data->LoadedSuccessfully)
return false; // no logging, the constructor has probably already logged
for (const std::string& eventId : data->EventIds)
{
+ if (m_loadedAudioOverrides.contains(eventId))
+ {
+ spdlog::warn("\"{}\" mod tried to override sound event \"{}\" but it is already overriden, skipping.", modName, eventId);
+ continue;
+ }
spdlog::info("Registering sound event {}", eventId);
m_loadedAudioOverrides.insert({eventId, data});
}
for (const auto& eventIdRegexData : data->EventIdsRegex)
{
+ if (m_loadedAudioOverridesRegex.contains(eventIdRegexData.first))
+ {
+ spdlog::warn(
+ "\"{}\" mod tried to override sound event regex \"{}\" but it is already overriden, skipping.",
+ modName,
+ eventIdRegexData.first);
+ continue;
+ }
spdlog::info("Registering sound event regex {}", eventIdRegexData.first);
m_loadedAudioOverridesRegex.insert({eventIdRegexData.first, data});
}
diff --git a/primedev/client/audio.h b/primedev/client/audio.h
index 15fd1a35..7cd0ddd1 100644
--- a/primedev/client/audio.h
+++ b/primedev/client/audio.h
@@ -15,7 +15,7 @@ enum class AudioSelectionStrategy
class EventOverrideData
{
public:
- EventOverrideData(const std::string&, const fs::path&);
+ EventOverrideData(const std::string&, const fs::path&, const std::vector<std::string>& registeredEvents);
EventOverrideData();
public:
@@ -35,7 +35,7 @@ public:
class CustomAudioManager
{
public:
- bool TryLoadAudioOverride(const fs::path&);
+ bool TryLoadAudioOverride(const fs::path&, std::string modName);
void ClearAudioOverrides();
std::shared_mutex m_loadingMutex;
diff --git a/primedev/mods/modmanager.cpp b/primedev/mods/modmanager.cpp
index edf69c9f..68f9bd0f 100644
--- a/primedev/mods/modmanager.cpp
+++ b/primedev/mods/modmanager.cpp
@@ -972,7 +972,7 @@ void ModManager::LoadMods()
{
if (fs::is_regular_file(file) && file.path().extension().string() == ".json")
{
- if (!g_CustomAudioManager.TryLoadAudioOverride(file.path()))
+ if (!g_CustomAudioManager.TryLoadAudioOverride(file.path(), mod.Name))
{
spdlog::warn("Mod {} has an invalid audio def {}", mod.Name, file.path().filename().string());
continue;