bool DragonAge2Engine::detectLanguages(Aurora::GameID UNUSED(game), const Common::UString &target, Aurora::Platform UNUSED(platform), std::vector<Aurora::Language> &languages) const { try { Common::UString tlkDir = Common::FilePath::findSubDirectory(target, "packages/core/data/talktables", true); if (tlkDir.empty()) return true; Common::FileList tlks; if (!tlks.addDirectory(tlkDir)) return true; for (size_t i = 0; i < Aurora::kLanguageMAX; i++) { Common::UString langStr = getLanguageString((Aurora::Language) i); if (langStr.empty()) continue; if (!tlks.contains("core_" + langStr + ".tlk", true)) continue; languages.push_back((Aurora::Language) i); } } catch (...) { } return true; }
Common::UString Module::getName(const Common::UString &module) { /* Return the localized name of the first (and only) area of the module, * which is the closest thing to the name of the module. * * To do that, if looks through the module directory for a matching RIM file * (case-insensitively) and opens it without indexing into the ResourceManager. * It then opens the module.ifo, grabs the name of the area, opens its ARE file * and returns the localized "Name" field. * * If there's any error while doing all this, an empty string is returned. */ try { const Common::FileList modules(ConfigMan.getString("KOTOR_moduleDir")); const Aurora::RIMFile rim(new Common::ReadFile(modules.findFirst(module + ".rim", true))); const uint32 ifoIndex = rim.findResource("module", Aurora::kFileTypeIFO); const Aurora::GFF3File ifo(rim.getResource(ifoIndex), MKTAG('I', 'F', 'O', ' ')); const Aurora::GFF3List &areas = ifo.getTopLevel().getList("Mod_Area_list"); if (areas.empty()) return ""; const uint32 areIndex = rim.findResource((*areas.begin())->getString("Area_Name"), Aurora::kFileTypeARE); const Aurora::GFF3File are(rim.getResource(areIndex), MKTAG('A', 'R', 'E', ' ')); return are.getTopLevel().getString("Name"); } catch (...) { } return ""; }
bool WitcherEngine::detectLanguages(Aurora::GameID UNUSED(game), const Common::UString &target, Aurora::Platform UNUSED(platform), std::vector<Aurora::Language> &languagesText, std::vector<Aurora::Language> &languagesVoice) const { try { Common::UString dataDir = Common::FilePath::findSubDirectory(target, "data", true); if (dataDir.empty()) return true; Common::FileList files; if (!files.addDirectory(dataDir)) return true; for (size_t i = 0; i < Aurora::kLanguageMAX; i++) { const uint32 langID = LangMan.getLanguageID((Aurora::Language) i); const Common::UString voiceKey = Common::UString::format("lang_%d.key" , langID); const Common::UString textKey = Common::UString::format("dialog_%d.tlk", langID); if (files.contains(voiceKey, true)) languagesVoice.push_back((Aurora::Language) i); if (files.contains(textKey, true)) languagesText.push_back((Aurora::Language) i); } } catch (...) { } return true; }
bool KotOR2Engine::detectLanguages(Aurora::GameID UNUSED(game), const Common::UString &target, Aurora::Platform platform, std::vector<Aurora::Language> &languages) const { try { Common::UString baseDir = target; if (platform == Aurora::kPlatformLinux) baseDir += "/steamassets"; else if (platform == Aurora::kPlatformMacOSX) baseDir += "/GameData"; Common::FileList files; if (!files.addDirectory(baseDir)) return true; Common::UString tlk = files.findFirst("dialog.tlk", true); if (tlk.empty()) return true; uint32 languageID = Aurora::TalkTable_TLK::getLanguageID(tlk); if (languageID == Aurora::kLanguageInvalid) return true; Aurora::Language language = LangMan.getLanguage(languageID); if (language == Aurora::kLanguageInvalid) return true; languages.push_back(language); } catch (...) { } return true; }
bool EngineManager::probeGame(GameInstance &game) const { game._gameID = Aurora::kGameIDUnknown; game._platform = Aurora::kPlatformUnknown; if (Common::FilePath::isDirectory(game._target)) { // Try to probe from that directory Common::FileList rootFiles; if (!rootFiles.addDirectory(game._target)) // Fatal: can't read the directory return false; return probeGame(game, rootFiles); } if (Common::FilePath::isRegularFile(game._target)) { // Try to probe from that file Common::File file; if (file.open(game._target)) return probeGame(game, file); } return false; }
ResourceManager::ChangeID ResourceManager::addResourceDir(const Common::UString &dir, const char *glob, int depth, uint32 priority) { // Find the directory Common::UString directory = Common::FilePath::findSubDirectory(_baseDir, dir, true); if (directory.empty()) throw Common::Exception("No such directory \"%s\"", dir.c_str()); // Find files Common::FileList files; files.addDirectory(directory, depth); ChangeID change = newChangeSet(); if (!glob) { // Add the files addResources(files, change, priority); return change; } // Find files matching the glob pattern Common::FileList globFiles; files.getSubList(glob, globFiles, true); // Add the files addResources(globFiles, change, priority); return change; }
bool NWN2Engine::detectLanguages(Aurora::GameID UNUSED(game), const Common::UString &target, Aurora::Platform UNUSED(platform), std::vector<Aurora::Language> &languages) const { try { Common::FileList files; if (!files.addDirectory(target)) return true; Common::UString tlk = files.findFirst("dialog.tlk", true); if (tlk.empty()) return true; uint32 languageID = Aurora::TalkTable_TLK::getLanguageID(tlk); if (languageID == Aurora::kLanguageInvalid) return true; Aurora::Language language = LangMan.getLanguage(languageID); if (language == Aurora::kLanguageInvalid) return true; languages.push_back(language); } catch (...) { } return true; }
bool NWN2EngineProbe::probe(const Common::UString &directory, const Common::FileList &rootFiles) const { // If either the ini file or the binary is found, this should be a valid path if (rootFiles.contains(".*/nwn2.ini", true)) return true; if (rootFiles.contains(".*/nwn2main.exe", true)) return true; return false; }
void ResourceManager::addResources(const Common::FileList &files, ChangeID &change, uint32 priority) { for (Common::FileList::const_iterator file = files.begin(); file != files.end(); ++file) { Resource res; res.priority = priority; res.source = kSourceFile; res.path = *file; res.type = getFileType(*file); addResource(res, Common::FilePath::getStem(*file), change); } }
Common::SeekableReadStream *Campaign::openMMD(const Common::UString &campaign) { const Common::FileList mmdFiles(ConfigMan.getString("WITCHER_moduleDir"), -1); for (Common::FileList::const_iterator c = mmdFiles.begin(); c != mmdFiles.end(); ++c) { if (!Common::FilePath::getFile(*c).equalsIgnoreCase(campaign + ".mmd")) continue; return new Common::ReadFile(*c); } throw Common::Exception("No such campaign \"%s\"", campaign.c_str()); }
Common::UString Campaign::getDirectory(const Common::UString &campaign) { const Common::FileList mmdFiles(ConfigMan.getString("WITCHER_moduleDir"), -1); for (Common::FileList::const_iterator c = mmdFiles.begin(); c != mmdFiles.end(); ++c) { if (!Common::FilePath::getFile(*c).equalsIgnoreCase(campaign + ".mmd")) continue; return Common::FilePath::relativize(ResMan.getDataBase(), Common::FilePath::getDirectory(*c)); } throw Common::Exception("No such campaign \"%s\"", campaign.c_str()); }
bool probe(const Common::UString &UNUSED(directory), const Common::FileList &rootFiles) const { // Don't accidentally trigger on NWN2 if (rootFiles.contains("/nwn2.ini", true)) return false; if (rootFiles.contains("/nwn2main.exe", true)) return false; // As a fallback, look for the nwn.ini, nwnplayer.ini or nwncdkey.ini return rootFiles.contains("/nwn.ini", true) || rootFiles.contains("/nwnplayer.ini", true) || rootFiles.contains("/nwncdkey.ini", true); }
bool TheWitcherEngineProbe::probe(const Common::UString &directory, const Common::FileList &rootFiles) const { // There should be a system directory Common::UString systemDir = Common::FilePath::findSubDirectory(directory, "system", true); if (systemDir.empty()) return false; // The system directory has to be readable Common::FileList systemFiles; if (!systemFiles.addDirectory(systemDir)) return false; // If either witcher.ini or witcher.exe exists, this should be a valid path return systemFiles.contains(".*/witcher.(exe|ini)", true); }
bool probe(const Common::UString &UNUSED(directory), const Common::FileList &rootFiles) const { // If the launcher binary is found, this should be a valid path if (rootFiles.contains("/daoriginslauncher.exe", true)) return true; return false; }
bool DragonAge2EngineProbe::probe(const Common::UString &directory, const Common::FileList &rootFiles) const { // If the launcher binary is found, this should be a valid path if (rootFiles.contains(".*/dragonage2launcher.exe", true)) return true; return false; }
Common::UString Module::getDescription(const Common::UString &module) { try { const Common::FileList modules(ConfigMan.getString("NWN2_moduleDir")); const Aurora::ERFFile mod(new Common::ReadFile(modules.findFirst(module + ".mod", true))); const uint32 ifoIndex = mod.findResource("module", Aurora::kFileTypeIFO); const Aurora::GFF3File ifo(mod.getResource(ifoIndex), MKTAG('I', 'F', 'O', ' ')); return ifo.getTopLevel().getString("Mod_Description"); } catch (...) { } return ""; }
void NWNEngine::getCharacters(std::vector<Common::UString> &characters, bool local) { characters.clear(); Common::UString pcDir = ConfigMan.getString(local ? "NWN_localPCDir" : "NWN_serverPCDir"); if (pcDir.empty()) return; Common::FileList chars; chars.addDirectory(pcDir); for (Common::FileList::const_iterator c = chars.begin(); c != chars.end(); ++c) { if (!Common::FilePath::getExtension(*c).equalsIgnoreCase(".bic")) continue; characters.push_back(Common::FilePath::getStem(*c)); } }
Common::UString ResourceManager::findArchive(const Common::UString &file, const DirectoryList &dirs, const Common::FileList &files) { Common::UString escapedFile = Common::FilePath::escapeStringLiteral(file); Common::FileList nameMatch; if (!files.getSubList(".*/" + escapedFile, nameMatch, true)) return ""; Common::UString realName; for (DirectoryList::const_iterator dir = dirs.begin(); dir != dirs.end(); ++dir) { Common::UString escapedPath = Common::FilePath::escapeStringLiteral(Common::FilePath::normalize(*dir)) + "/" + escapedFile; if (!(realName = nameMatch.findFirst(escapedPath, true)).empty()) return realName; } return ""; }
bool probe(const Common::UString &directory, const Common::FileList &rootFiles) const { /* If we find the Xbox executable and a Dragon Age specific file, * this should be a valid path. */ if (rootFiles.contains("default.xex", true) && Common::FileList(Common::FilePath::findSubDirectory(directory, "modules/single player", true)).contains("singleplayer.cif", true)) return true; return false; }
void Console::updateMusic() { _music.clear(); _maxSizeMusic = 0; const Common::FileList music(Common::FilePath::findSubDirectory(ResMan.getDataBase(), "streammusic", true)); for (Common::FileList::const_iterator m = music.begin(); m != music.end(); ++m) { if (!Common::FilePath::getExtension(*m).equalsIgnoreCase(".wav")) continue; _music.push_back(Common::FilePath::getStem(*m)); _maxSizeMusic = MAX(_maxSizeMusic, _music.back().size()); } std::sort(_music.begin(), _music.end(), Common::UString::iless()); setArguments("playmusic", _music); }
void NWNEngine::getModules(std::vector<Common::UString> &modules) { modules.clear(); Common::UString moduleDir = ConfigMan.getString("NWN_extraModuleDir"); if (moduleDir.empty()) return; Common::FileList mods; mods.addDirectory(moduleDir); for (Common::FileList::const_iterator m = mods.begin(); m != mods.end(); ++m) { if (!Common::FilePath::getExtension(*m).equalsIgnoreCase(".mod")) continue; modules.push_back(Common::FilePath::getStem(*m)); } std::sort(modules.begin(), modules.end(), Common::UString::iless()); }
void Game::getCampaigns(std::vector<Common::UString> &campaigns) { campaigns.clear(); const Common::UString directory = ConfigMan.getString("NWN2_campaignDir"); const Common::FileList camFiles(directory, -1); for (Common::FileList::const_iterator c = camFiles.begin(); c != camFiles.end(); ++c) { if (!Common::FilePath::getFile(*c).equalsIgnoreCase("campaign.cam")) continue; const Common::UString cam = Common::FilePath::relativize(directory, Common::FilePath::getDirectory(*c)); if (cam.empty() || (cam == ".")) continue; campaigns.push_back(cam); } std::sort(campaigns.begin(), campaigns.end(), Common::UString::iless()); }
bool NWNEngineProbe::probe(const Common::UString &directory, const Common::FileList &rootFiles) const { // Don't accidentally trigger on NWN2 if (rootFiles.contains(".*/nwn2.ini", true)) return false; if (rootFiles.contains(".*/nwn2main.exe", true)) return false; // If either the ini file or a binary is found, this should be a valid path if (rootFiles.contains(".*/nwn.ini", true)) return true; if (rootFiles.contains(".*/(nw|nwn)main.exe", true)) return true; if (rootFiles.contains(".*/(nw|nwn)main", true)) return true; return false; }
void Campaigns::findCampaigns() { status("Looking for campaigns..."); const Common::UString baseDir = ResMan.getDataBase(); // Single player const Common::UString spDir = Common::FilePath::findSubDirectory(baseDir, "modules/campaign_base", true); const Common::FileList spFiles(spDir, -1); addCampaign(readCampaign(spFiles.findFirst("campaign_base.cif", true))); // DLCs const Common::UString dlcDir = Common::FilePath::findSubDirectory(baseDir, "addins", true); std::list<Common::UString> dlcDirs; Common::FilePath::getSubDirectories(dlcDir, dlcDirs); for (std::list<Common::UString>::const_iterator d = dlcDirs.begin(); d != dlcDirs.end(); ++d) { const Common::FileList dlcFiles(*d); const Common::FileList moduleFiles(Common::FilePath::findSubDirectory(*d, "module", true)); const Common::UString cifFile = moduleFiles.findFirstGlob(".*\\.cif", true); const Common::UString manifestFile = dlcFiles.findFirst("/manifest.xml", true); const Common::UString addinBase = Common::FilePath::relativize(dlcDir, *d); addCampaign(readCampaign(cifFile, manifestFile, addinBase)); } }
void ResourceManager::addArchiveDir(ArchiveType archive, const Common::UString &dir) { if (archive == kArchiveNDS || archive == kArchiveHERF) return; assert((archive >= 0) && (archive < kArchiveMAX)); Common::UString directory = Common::FilePath::findSubDirectory(_baseDir, dir, true); if (directory.empty()) throw Common::Exception("No such directory \"%s\"", dir.c_str()); Common::FileList dirFiles; if (!dirFiles.addDirectory(directory)) throw Common::Exception("Can't read directory \"%s\"", directory.c_str()); dirFiles.getSubList(kArchiveGlob[archive], _archiveFiles[archive], true); // If we're adding an ERF directory and .rim files are actually ERFs, add those too if ((archive == kArchiveERF) && _rimsAreERFs) dirFiles.getSubList(kArchiveGlob[kArchiveRIM], _archiveFiles[archive], true); _archiveDirs[archive].push_back(directory); }
void SaveLoadMenu::addSavedGameItems(WidgetListBox *listBox) { Common::FileList dirs; Common::UString savesDir = Common::FilePath::normalize(ConfigMan.getString("path") + "/saves"); dirs.addSubDirectories(savesDir); Common::UString slotTextFormat = TalkMan.getString(1594); dirs.sort(true); for (Common::FileList::const_iterator it = dirs.begin(); it != dirs.end(); ++it) { Common::UString saveDir = *it; Common::UString baseName; try { baseName = getBaseNameFromDirectory(saveDir); } catch (Common::Exception &e) { e.add("Failed to get save base name from directory \"%s\"", saveDir.c_str()); printException(e, "WARNING: "); continue; } if (_type == kSaveLoadMenuTypeSave && !baseName.contains("Game")) continue; _saveDirs.push_back(saveDir); SavedGame *save = SavedGame::load(saveDir); uint32 timePlayed = save->getTimePlayed(); Common::UString slotText(slotTextFormat); slotText.replaceAll("Game <CUSTOM0>", baseName); slotText.replaceAll("<CUSTOM1>", Common::composeString(timePlayed / 3600)); slotText.replaceAll("<CUSTOM2>", Common::composeString(timePlayed % 3600 / 60)); if (baseName.contains("Game")) slotText += "\r\n" + save->getName(); delete save; listBox->addItem(slotText); } }
bool GameInstanceEngine::probe() { if (Common::FilePath::isDirectory(_target)) { // Try to probe from that directory Common::FileList rootFiles; if (!rootFiles.addDirectory(_target)) // Fatal: can't read the directory return false; return probe(rootFiles); } if (Common::FilePath::isRegularFile(_target)) { // Try to probe from that file Common::ReadFile file; if (file.open(_target)) return probe(file); } return false; }
void Game::getModules(std::vector<Common::UString> &modules) { modules.clear(); Common::UString moduleDir = ConfigMan.getString("KOTOR_moduleDir"); if (moduleDir.empty()) return; Common::FileList mods; mods.addDirectory(moduleDir); for (Common::FileList::const_iterator m = mods.begin(); m != mods.end(); ++m) { Common::UString file = m->toLower(); if (!file.endsWith("_s.rim")) continue; file = Common::FilePath::getStem(file); file.truncate(file.size() - Common::UString("_s").size()); modules.push_back(file); } std::sort(modules.begin(), modules.end(), Common::UString::iless()); }
bool KotOR2EngineProbeLinux::probe(const Common::UString &directory, const Common::FileList &rootFiles) const { // The game binary found in the Aspyr Linux port if (!rootFiles.contains("/KOTOR2", false)) return false; // The directory containing what was originally within the PE resources if (Common::FilePath::findSubDirectory(directory, "resources").empty()) return false; // The directory containing the original game data files if (Common::FilePath::findSubDirectory(directory, "steamassets").empty()) return false; return true; }
void Campaign::findCampaigns() { Common::UString moduleDir = ConfigMan.getString("WITCHER_moduleDir"); if (moduleDir.empty()) return; Common::FileList modules; if (!modules.addDirectory(moduleDir, -1)) return; Common::FileList mmdFiles; if (!modules.getSubListGlob(".*\\.mmd", true, mmdFiles)) return; for (Common::FileList::const_iterator c = mmdFiles.begin(); c != mmdFiles.end(); ++c) { CampaignDescription desc; desc.directory = Common::FilePath::relativize(moduleDir, Common::FilePath::getDirectory(*c)); if (!readCampaign(*c, desc)) continue; _campaigns.push_back(desc); } }