25 #include <Overlay/OgreOverlayManager.h>
26 #include <Overlay/OgreOverlay.h>
27 #include <Plugins/ParticleFX/OgreBoxEmitterFactory.h>
47 #ifdef USE_ANGELSCRIPT
50 #endif // USE_ANGELSCRIPT
54 #include <OgreFileSystem.h>
56 #include <rapidjson/stringbuffer.h>
57 #include <rapidjson/writer.h>
67 #define DECLARE_RESOURCE_PACK(_FIELD_, _NAME_, _RESOURCE_GROUP_) \
68 const ContentManager::ResourcePack ContentManager::ResourcePack::_FIELD_(_NAME_, _RESOURCE_GROUP_);
98 void ContentManager::AddResourcePack(
ResourcePack const& resource_pack, std::string
const& override_rgn)
100 Ogre::ResourceGroupManager& rgm = Ogre::ResourceGroupManager::getSingleton();
102 Ogre::String rg_name;
103 if (!override_rgn.empty())
105 rg_name = override_rgn;
116 std::stringstream log_msg;
117 log_msg <<
"[RoR|ContentManager] Loading resource pack \"" << resource_pack.
name <<
"\" to group \"" << rg_name <<
"\"";
119 std::string zip_path = dir_path +
".zip";
122 log_msg <<
" (ZIP archive)";
124 rgm.addResourceLocation(zip_path,
"Zip", rg_name);
130 log_msg <<
" (directory)";
132 rgm.addResourceLocation(dir_path,
"FileSystem", rg_name);
136 log_msg <<
" failed, data not found.";
137 throw std::runtime_error(log_msg.str());
141 if (override_rgn.empty())
143 rgm.initialiseResourceGroup(rg_name);
147 void ContentManager::InitContentManager()
149 ResourceGroupManager::getSingleton().addResourceLocation(
151 ResourceGroupManager::getSingleton().addResourceLocation(
153 ResourceGroupManager::getSingleton().addResourceLocation(
155 ResourceGroupManager::getSingleton().addResourceLocation(
158 Ogre::ScriptCompilerManager::getSingleton().setListener(
this);
167 if (!Ogre::ResourceGroupManager::getSingleton().getLoadingListener())
168 Ogre::ResourceGroupManager::getSingleton().setLoadingListener(
this);
174 this->AddResourcePack(ResourcePack::MYGUI);
175 this->AddResourcePack(ResourcePack::DASHBOARDS);
181 LOG(
"RoR|ContentManager: Registering Particle Box Emitter");
183 ParticleSystemManager::getSingleton().addRendererFactory(mParticleSystemRendererFact);
192 #ifdef USE_ANGELSCRIPT
195 ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact);
199 ParticleSystemManager::getSingleton().addAffectorFactory(pAffFact);
200 #endif // USE_ANGELSCRIPT
204 LOG(
"RoR|ContentManager: Creating Sound Manager");
209 AddResourcePack(ResourcePack::SOUNDS);
212 LOG(
"RoR|ContentManager: Loading filesystems");
214 LOG(
"RoR|ContentManager: Registering colored text overlay factory");
216 OverlayManager::getSingleton().addOverlayElementFactory(pCT);
219 if (TextureManager::getSingletonPtr())
220 TextureManager::getSingleton().setDefaultNumMipmaps(5);
222 TextureFilterOptions tfo = TFO_NONE;
225 case GfxTexFilter::ANISOTROPIC: tfo = TFO_ANISOTROPIC;
break;
226 case GfxTexFilter::TRILINEAR: tfo = TFO_TRILINEAR;
break;
227 case GfxTexFilter::BILINEAR: tfo = TFO_BILINEAR;
break;
228 case GfxTexFilter::NONE: tfo = TFO_NONE;
break;
230 MaterialManager::getSingleton().setDefaultAnisotropy(Math::Clamp(
App::gfx_anisotropy->getInt(), 1, 16));
231 MaterialManager::getSingleton().setDefaultTextureFiltering(tfo);
234 LOG(
"RoR|ContentManager: Calling initialiseAllResourceGroups()");
237 ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
239 catch (Ogre::Exception& e)
241 LOG(
"RoR|ContentManager: catched error while initializing Resource groups: " + e.getFullDescription());
259 ResourceGroupManager::getSingleton().addResourceLocation(
261 ResourceGroupManager::getSingleton().addResourceLocation(
269 ResourceGroupManager::getSingleton().addResourceLocation(extra_mod_path ,
"FileSystem",
RGN_CONTENT);
276 std::string objects =
PathCombine(
"resources",
"beamobjects.zip");
281 ResourceGroupManager::getSingleton().createResourceGroup(
RGN_TEMP,
false);
285 ResourceGroupManager::getSingleton().addResourceLocation(extra_mod_path ,
"FileSystem",
RGN_TEMP,
true);
296 FileInfoListPtr dirs = ResourceGroupManager::getSingleton().findResourceFileInfo(
RGN_TEMP,
"*",
true);
297 for (
const auto& dir_fileinfo : *dirs)
299 if (!dir_fileinfo.archive)
301 String fullpath =
PathCombine(dir_fileinfo.archive->getName(), dir_fileinfo.filename);
302 ResourceGroupManager::getSingleton().addResourceLocation(fullpath,
"FileSystem",
RGN_CONTENT,
false,
false);
304 ResourceGroupManager::getSingleton().destroyResourceGroup(
RGN_TEMP);
308 if (validity == CacheValidity::UNKNOWN)
314 ResourceGroupManager::getSingleton().destroyResourceGroup(
RGN_CONTENT);
318 Ogre::DataStreamPtr ContentManager::resourceLoading(
const Ogre::String& name,
const Ogre::String& group, Ogre::Resource* resource)
320 return Ogre::DataStreamPtr();
323 void ContentManager::resourceStreamOpened(
const Ogre::String& name,
const Ogre::String& group, Ogre::Resource* resource, Ogre::DataStreamPtr& dataStream)
327 bool ContentManager::resourceCollision(Ogre::Resource* resource, Ogre::ResourceManager* resourceManager)
334 RoR::LogFormat(
"[RoR|ContentManager] Skipping resource with duplicate name: '%s' (origin: '%s')",
335 resource->getName().c_str(), resource->getOrigin().c_str());
339 bool ContentManager::handleEvent(ScriptCompiler *compiler, ScriptCompilerEvent *evt,
void *retval)
341 if (evt->mType == CreateMaterialScriptCompilerEvent::eventType)
345 auto* matEvent =
static_cast<CreateMaterialScriptCompilerEvent*
>(evt);
346 if (matEvent->mName.empty())
348 RoR::LogFormat(
"[RoR] Got malformed material (empty name) from file: '%s' - forcing OGRE to fail loading.",
349 matEvent->mFile.c_str());
355 else if (evt->mType == CreateParticleSystemScriptCompilerEvent::eventType)
359 auto* particleEvent =
static_cast<CreateParticleSystemScriptCompilerEvent*
>(evt);
360 if (Ogre::ParticleSystemManager::getSingleton().getTemplate(particleEvent->mName) !=
nullptr)
363 RoR::LogFormat(
"[RoR] Duplicate particle system name '%s' in file: '%s' - forcing OGRE to fail loading.",
364 particleEvent->mName.c_str(), particleEvent->mFile.c_str());
372 void ContentManager::InitManagedMaterials(std::string
const & rg_name)
381 ResourceGroupManager::getSingleton().addResourceLocation(
PathCombine(managed_materials_dir,
"shadows/pssm/on/shared"),
"FileSystem", rg_name);
383 ResourceGroupManager::getSingleton().addResourceLocation(
PathCombine(managed_materials_dir,
"shadows/pssm/on"),
"FileSystem", rg_name);
387 ResourceGroupManager::getSingleton().addResourceLocation(
PathCombine(managed_materials_dir,
"shadows/pssm/off"),
"FileSystem", rg_name);
390 ResourceGroupManager::getSingleton().addResourceLocation(
PathCombine(managed_materials_dir,
"texture"),
"FileSystem", rg_name);
393 ResourceGroupManager::getSingleton().addResourceLocation(managed_materials_dir,
"FileSystem", rg_name);
396 ResourceGroupManager::getSingleton().initialiseResourceGroup(rg_name);
399 void ContentManager::LoadGameplayResources()
401 if (!m_base_resource_loaded)
403 this->AddResourcePack(ContentManager::ResourcePack::AIRFOILS);
404 this->AddResourcePack(ContentManager::ResourcePack::TEXTURES);
405 this->AddResourcePack(ContentManager::ResourcePack::FAMICONS);
406 this->AddResourcePack(ContentManager::ResourcePack::MATERIALS);
407 this->AddResourcePack(ContentManager::ResourcePack::MESHES);
408 this->AddResourcePack(ContentManager::ResourcePack::OVERLAYS);
409 this->AddResourcePack(ContentManager::ResourcePack::PARTICLES);
411 m_base_resource_loaded =
true;
415 this->AddResourcePack(ContentManager::ResourcePack::HYDRAX);
418 this->AddResourcePack(ContentManager::ResourcePack::CAELUM);
421 this->AddResourcePack(ContentManager::ResourcePack::SKYX);
424 this->AddResourcePack(ContentManager::ResourcePack::PAGED);
427 std::string ContentManager::ListAllUserContent()
429 std::stringstream buf;
431 auto dir_list = Ogre::ResourceGroupManager::getSingleton().listResourceFileInfo(
RGN_CONTENT,
true);
432 for (
auto dir: *dir_list)
434 buf << dir.filename << std::endl;
438 std::regex file_whitelist(
"^.\\.(airplane|boat|car|fixed|load|machine|skin|terrn2|train|truck)$", std::regex::icase);
440 auto file_list = Ogre::ResourceGroupManager::getSingleton().listResourceFileInfo(
RGN_CONTENT,
false);
441 for (
auto file: *file_list)
443 if ((
file.archive !=
nullptr) || std::regex_match(
file.filename, file_whitelist))
445 buf <<
file.filename << std::endl;
452 bool ContentManager::LoadAndParseJson(std::string
const& filename, std::string
const& rg_name, rapidjson::Document& j_doc)
456 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(filename, rg_name);
457 Ogre::String json_str = stream->getAsString();
458 rapidjson::MemoryStream j_stream(json_str.data(), json_str.length());
459 j_doc.ParseStream<rapidjson::kParseNanAndInfFlag>(j_stream);
461 catch (Ogre::FileNotFoundException)
465 catch (std::exception& e)
467 RoR::LogFormat(
"[RoR] Failed to open or read json file '%s' (resource group '%s'), message: '%s'",
468 filename.c_str(), rg_name.c_str(), e.what());
472 if (j_doc.HasParseError())
474 RoR::LogFormat(
"[RoR] Error parsing JSON file '%s' (resource group '%s')",
475 filename.c_str(), rg_name.c_str());
482 bool ContentManager::SerializeAndWriteJson(std::string
const& filename, std::string
const& rg_name, rapidjson::Document& j_doc)
485 rapidjson::StringBuffer buffer;
486 rapidjson::Writer<rapidjson::StringBuffer, rapidjson::UTF8<>, rapidjson::UTF8<>,
487 rapidjson::CrtAllocator, rapidjson::kWriteNanAndInfFlag>
489 j_doc.Accept(writer);
494 Ogre::DataStreamPtr stream
495 = Ogre::ResourceGroupManager::getSingleton().createResource(
496 filename, rg_name,
true);
497 size_t written = stream->write(buffer.GetString(), buffer.GetSize());
498 if (written < buffer.GetSize())
500 RoR::LogFormat(
"[RoR] Error writing JSON file '%s' (resource group '%s'), ",
501 "only written %u out of %u bytes!",
502 filename.c_str(), rg_name.c_str(), written, buffer.GetSize());
507 catch (std::exception& e)
509 RoR::LogFormat(
"[RoR] Error writing JSON file '%s' (resource group '%s'), message: '%s'",
510 filename.c_str(), rg_name.c_str(), e.what());
515 bool ContentManager::DeleteDiskFile(std::string
const& filename, std::string
const& rg_name)
519 Ogre::ResourceGroupManager::getSingleton().deleteResource(filename, rg_name);
522 catch (std::exception& e)
524 RoR::LogFormat(
"[RoR|ModCache] Error deleting file '%s' (resource group '%s'), message: '%s'",
525 filename.c_str(), rg_name.c_str(), e.what());