Esempio n. 1
0
void Profile::writeModlistNow()
{
  if (!m_Directory.exists()) return;

  try {
    QString fileName = getModlistFileName();
    SafeWriteFile file(fileName);

    file->write(QString("# This file was automatically generated by Mod Organizer.\r\n").toUtf8());
    if (m_ModStatus.empty()) {
      return;
    }

    for (int i = m_ModStatus.size() - 1; i >= 0; --i) {
      // the priority order was inverted on load so it has to be inverted again
      unsigned int index = m_ModIndexByPriority[i];
      if (index != UINT_MAX) {
        ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
        std::vector<ModInfo::EFlag> flags = modInfo->getFlags();
        if ((modInfo->getFixedPriority() == INT_MIN)) {
          if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) != flags.end()) {
            file->write("*");
          } else if (m_ModStatus[index].m_Enabled) {
            file->write("+");
          } else {
            file->write("-");
          }
          file->write(modInfo->name().toUtf8());
          file->write("\r\n");
        }
      }
    }

    if (file.commitIfDifferent(m_LastModlistHash)) {
      qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData());
    }
  } catch (const std::exception &e) {
    reportError(tr("failed to write mod list: %1").arg(e.what()));
    return;
  }
}
Esempio n. 2
0
void Profile::refreshModStatus()
{
  QFile file(getModlistFileName());
  if (!file.open(QIODevice::ReadOnly)) {
    throw MyException(tr("\"%1\" is missing or inaccessible").arg(getModlistFileName()));
  }

  bool modStatusModified = false;
  m_ModStatus.clear();
  m_ModStatus.resize(ModInfo::getNumMods());

  std::set<QString> namesRead;

  // load mods from file and update enabled state and priority for them
  int index = 0;
  while (!file.atEnd()) {
    QByteArray line = file.readLine().trimmed();
    bool enabled = true;
    QString modName;
    if (line.length() == 0) {
      // empty line
      continue;
    } else if (line.at(0) == '#') {
      // comment line
      continue;
    } else if (line.at(0) == '-') {
      enabled = false;
      modName = QString::fromUtf8(line.mid(1).trimmed().constData());
    } else if ((line.at(0) == '+')
               || (line.at(0) == '*')) {
      modName = QString::fromUtf8(line.mid(1).trimmed().constData());
    } else {
      modName = QString::fromUtf8(line.trimmed().constData());
    }
    if (modName.size() > 0) {
      QString lookupName = modName;
      if (namesRead.find(lookupName) != namesRead.end()) {
        continue;
      } else {
        namesRead.insert(lookupName);
      }
      unsigned int modIndex = ModInfo::getIndex(lookupName);
      if (modIndex != UINT_MAX) {
        ModInfo::Ptr info = ModInfo::getByIndex(modIndex);
        if ((modIndex < m_ModStatus.size())
            && (info->getFixedPriority() == INT_MIN)) {
          m_ModStatus[modIndex].m_Enabled = enabled;
          if (m_ModStatus[modIndex].m_Priority == -1) {
            if (static_cast<size_t>(index) >= m_ModStatus.size()) {
              throw MyException(tr("invalid index %1").arg(index));
            }
            m_ModStatus[modIndex].m_Priority = index++;
          }
        } else {
          qWarning("no mod state for \"%s\" (profile \"%s\")",
                   qPrintable(modName), m_Directory.path().toUtf8().constData());
          // need to rewrite the modlist to fix this
          modStatusModified = true;
        }
      } else {
        qDebug("mod \"%s\" (profile \"%s\") not found",
               qPrintable(modName), m_Directory.path().toUtf8().constData());
        // need to rewrite the modlist to fix this
        modStatusModified = true;
      }
    }
  }

  int numKnownMods = index;

  int topInsert = 0;

  // invert priority order to match that of the pluginlist. Also
  // give priorities to mods not referenced in the profile
  for (size_t i = 0; i < m_ModStatus.size(); ++i) {
    ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
    if (modInfo->alwaysEnabled()) {
      m_ModStatus[i].m_Enabled = true;
    }

    if (modInfo->getFixedPriority() == INT_MAX) {
      continue;
    }

    if (m_ModStatus[i].m_Priority != -1) {
      m_ModStatus[i].m_Priority = numKnownMods - m_ModStatus[i].m_Priority - 1;
    } else {
      if (static_cast<size_t>(index) >= m_ModStatus.size()) {
        throw MyException(tr("invalid index %1").arg(index));
      }
      if (modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) {
        m_ModStatus[i].m_Priority = --topInsert;
      } else {
        m_ModStatus[i].m_Priority = index++;
      }
      // also, mark the mod-list as changed
      modStatusModified = true;
    }
  }
  // to support insertion of new mods at the top we may now have mods with negative priority. shift them all up
  // to align priority with 0
  if (topInsert < 0) {
    int offset = topInsert * -1;
    for (size_t i = 0; i < m_ModStatus.size(); ++i) {
      ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
      if (modInfo->getFixedPriority() == INT_MAX) {
        continue;
      }

      m_ModStatus[i].m_Priority += offset;
    }
  }

  file.close();
  updateIndices();
  if (modStatusModified) {
    m_ModListWriter.write();
  }
}