Ejemplo n.º 1
0
Plugin::Plugin(const Game& game, const std::string& name, const bool headerOnly) :
  PluginMetadata(name),
  libespm::Plugin(game.LibespmId()),
  isEmpty_(true),
  isActive_(false),
  loadsArchive_(false),
  crc_(0),
  numOverrideRecords_(0) {
  try {
    boost::filesystem::path filepath = game.DataPath() / Name();

    // In case the plugin is ghosted.
    if (!boost::filesystem::exists(filepath) && boost::filesystem::exists(filepath.string() + ".ghost"))
      filepath += ".ghost";

    load(filepath, headerOnly);

    isEmpty_ = getRecordAndGroupCount() == 0;

    if (!headerOnly) {
      BOOST_LOG_TRIVIAL(trace) << Name() << ": Caching CRC value.";
      crc_ = GetCrc32(filepath);
    }

    BOOST_LOG_TRIVIAL(trace) << Name() << ": Counting override FormIDs.";
    for (const auto& formID : getFormIds()) {
      if (!boost::iequals(formID.getPluginName(), Name()))
        ++numOverrideRecords_;
    }

    //Also read Bash Tags applied and version string in description.
    string text = getDescription();
    BOOST_LOG_TRIVIAL(trace) << Name() << ": " << "Attempting to extract Bash Tags from the description.";
    size_t pos1 = text.find("{{BASH:");
    if (pos1 != string::npos && pos1 + 7 != text.length()) {
      pos1 += 7;

      size_t pos2 = text.find("}}", pos1);
      if (pos2 != string::npos && pos1 != pos2) {
        text = text.substr(pos1, pos2 - pos1);

        std::vector<string> bashTags;
        boost::split(bashTags, text, [](char c) { return c == ','; });

        for (auto &tag : bashTags) {
          boost::trim(tag);
          BOOST_LOG_TRIVIAL(trace) << Name() << ": " << "Extracted Bash Tag: " << tag;
          tags_.insert(Tag(tag));
        }
      }
    }
    // Get whether the plugin is active or not.
    isActive_ = game.LoadOrderHandler::IsPluginActive(Name());

    // Get whether the plugin loads an archive (BSA/BA2) or not.
    const string archiveExtension = game.GetArchiveFileExtension();

    if (game.Type() == GameType::tes5) {
        // Skyrim plugins only load BSAs that exactly match their basename.
      loadsArchive_ = boost::filesystem::exists(game.DataPath() / (Name().substr(0, Name().length() - 4) + archiveExtension));
    } else if (game.Type() != GameType::tes4 || boost::iends_with(Name(), ".esp")) {
        //Oblivion .esp files and FO3, FNV, FO4 plugins can load archives which begin with the plugin basename.
      string basename = Name().substr(0, Name().length() - 4);
      for (boost::filesystem::directory_iterator it(game.DataPath()); it != boost::filesystem::directory_iterator(); ++it) {
        if (boost::iequals(it->path().extension().string(), archiveExtension) && boost::istarts_with(it->path().filename().string(), basename)) {
          loadsArchive_ = true;
          break;
        }
      }
    }
  } catch (std::exception& e) {
    BOOST_LOG_TRIVIAL(error) << "Cannot read plugin file \"" << name << "\". Details: " << e.what();
    messages_.push_back(Message(MessageType::error, (boost::format(boost::locale::translate("Cannot read \"%1%\". Details: %2%")) % name % e.what()).str()));
  }

  BOOST_LOG_TRIVIAL(trace) << Name() << ": " << "Plugin loading complete.";
}