Skip to content

Commit

Permalink
Avoid mixing up truckfiles when filename isn't unique.
Browse files Browse the repository at this point in the history
Fixes RigsOfRods#3166

Problem: When spawning an actor, the cache entry was always looked up via truckfile name, even if it was already known from the Selector UI. This potentially caused mixups.

Fix: Use the entry provided by Selector UI.
  • Loading branch information
ohlidalp committed Sep 1, 2024
1 parent 012c38a commit ee18140
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 28 deletions.
3 changes: 1 addition & 2 deletions source/main/GameContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,7 @@ ActorPtr GameContext::SpawnActor(ActorSpawnRequest& rq)
rq.asr_cache_entry = App::GetCacheSystem()->FindEntryByFilename(LT_AllBeam, /*partial:*/false, rq.asr_filename);
}

RigDef::DocumentPtr def = m_actor_manager.FetchActorDef(
rq.asr_filename, rq.asr_origin == ActorSpawnRequest::Origin::TERRN_DEF);
RigDef::DocumentPtr def = m_actor_manager.FetchActorDef(rq);
if (def == nullptr)
{
return nullptr; // Error already reported
Expand Down
43 changes: 18 additions & 25 deletions source/main/physics/ActorManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1254,44 +1254,37 @@ void HandleErrorLoadingTruckfile(std::string filename, std::string exception_msg
HandleErrorLoadingFile("actor", filename, exception_msg);
}

RigDef::DocumentPtr ActorManager::FetchActorDef(std::string filename, bool predefined_on_terrain)
RigDef::DocumentPtr ActorManager::FetchActorDef(RoR::ActorSpawnRequest& rq)
{
// Find the user content
CacheEntryPtr cache_entry = App::GetCacheSystem()->FindEntryByFilename(LT_AllBeam, /*partial=*/false, filename);
if (cache_entry == nullptr)
// Check the actor exists in mod cache
if (rq.asr_cache_entry == nullptr)
{
HandleErrorLoadingTruckfile(filename, "Truckfile not found in ModCache (probably not installed)");
HandleErrorLoadingTruckfile(rq.asr_filename, "Truckfile not found in ModCache (probably not installed)");
return nullptr;
}

// If already parsed, re-use
if (cache_entry->actor_def != nullptr)
if (rq.asr_cache_entry->actor_def != nullptr)
{
return cache_entry->actor_def;
return rq.asr_cache_entry->actor_def;
}

// Load the 'truckfile'
try
{
Ogre::String resource_filename = filename;
Ogre::String resource_groupname;
if (!App::GetCacheSystem()->CheckResourceLoaded(resource_filename, resource_groupname)) // Validates the filename and finds resource group
{
HandleErrorLoadingTruckfile(filename, "Truckfile not found");
return nullptr;
}
Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(resource_filename, resource_groupname);
App::GetCacheSystem()->LoadResource(rq.asr_cache_entry);
Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(rq.asr_cache_entry->fname, rq.asr_cache_entry->resource_group);

if (stream.isNull() || !stream->isReadable())
{
HandleErrorLoadingTruckfile(filename, "Unable to open/read truckfile");
HandleErrorLoadingTruckfile(rq.asr_cache_entry->fname, "Unable to open/read truckfile");
return nullptr;
}

RoR::LogFormat("[RoR] Parsing truckfile '%s'", resource_filename.c_str());
RoR::LogFormat("[RoR] Parsing truckfile '%s'", rq.asr_cache_entry->fname.c_str());
RigDef::Parser parser;
parser.Prepare();
parser.ProcessOgreStream(stream.getPointer(), resource_groupname);
parser.ProcessOgreStream(stream.getPointer(), rq.asr_cache_entry->resource_group);
parser.Finalize();

auto def = parser.GetFile();
Expand All @@ -1302,15 +1295,15 @@ RigDef::DocumentPtr ActorManager::FetchActorDef(std::string filename, bool prede
RigDef::Validator validator;
validator.Setup(def);

if (predefined_on_terrain)
if (rq.asr_origin == ActorSpawnRequest::Origin::TERRN_DEF)
{
// Workaround: Some terrains pre-load truckfiles with special purpose:
// "soundloads" = play sound effect at certain spot
// "fixes" = structures of N/B fixed to the ground
// These files can have no beams. Possible extensions: .load or .fixed
std::string file_extension = filename.substr(filename.find_last_of('.'));
std::string file_extension = rq.asr_cache_entry->fname.substr(rq.asr_cache_entry->fname.find_last_of('.'));
Ogre::StringUtil::toLowerCase(file_extension);
if ((file_extension == ".load") | (file_extension == ".fixed"))
if ((file_extension == ".load") || (file_extension == ".fixed"))
{
validator.SetCheckBeams(false);
}
Expand All @@ -1320,22 +1313,22 @@ RigDef::DocumentPtr ActorManager::FetchActorDef(std::string filename, bool prede

def->hash = Sha1Hash(stream->getAsString());

cache_entry->actor_def = def;
rq.asr_cache_entry->actor_def = def;
return def;
}
catch (Ogre::Exception& oex)
{
HandleErrorLoadingTruckfile(filename, oex.getFullDescription().c_str());
HandleErrorLoadingTruckfile(rq.asr_cache_entry->fname, oex.getDescription().c_str());
return nullptr;
}
catch (std::exception& stex)
{
HandleErrorLoadingTruckfile(filename, stex.what());
HandleErrorLoadingTruckfile(rq.asr_cache_entry->fname, stex.what());
return nullptr;
}
catch (...)
{
HandleErrorLoadingTruckfile(filename, "<Unknown exception occurred>");
HandleErrorLoadingTruckfile(rq.asr_cache_entry->fname, "<Unknown exception occurred>");
return nullptr;
}
}
Expand Down
2 changes: 1 addition & 1 deletion source/main/physics/ActorManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class ActorManager


void UpdateInputEvents(float dt);
RigDef::DocumentPtr FetchActorDef(std::string filename, bool predefined_on_terrain = false);
RigDef::DocumentPtr FetchActorDef(RoR::ActorSpawnRequest& rq);

#ifdef USE_SOCKETW
void HandleActorStreamData(std::vector<RoR::NetRecvPacket> packet);
Expand Down

0 comments on commit ee18140

Please sign in to comment.