Example #1
0
void SecurityManager::loadMembers()
{
    if (isSql()) {
        loadSqlMembers();
        return;
    }
    const char *path = "serverdb/members.txt";
    const char *backup = "serverdb/members.backup.txt";
    {
        QDir d;
        d.mkdir("serverdb");
    }

    if (!QFile::exists(path) && QFile::exists(backup)) {
        QFile::rename(backup, path);
    }

    memberFile.setFileName(path);
    if (!memberFile.open(QFile::ReadWrite)) {
        throw QObject::tr("Error: cannot open the file that contains the members (%1)").arg(path);
    }

    int pos = memberFile.pos();
    while (!memberFile.atEnd()) {
        QByteArray arr = memberFile.readLine();
        QString s = QString::fromUtf8(arr.constData(), std::max(0,arr.length()-1)); //-1 to remove the \n

        QStringList ls = s.split('%');

        if (ls.size() >= 6 && isValid(ls[0])) {
            Member m (ls[0], ls[1].trimmed(), ls[2][0].toLatin1() - '0', ls[2][1] == '1', ls[3].trimmed().toLatin1(), ls[4].trimmed().toLatin1(), ls[5].trimmed());

            if (ls.size() >= 7) {
                m.ban_expire_time = ls[6].toInt();
            }

            m.filepos = pos;
            members[ls[0]] = m;

            /* Update pos for next iteration */
            pos = memberFile.pos();

            if (m.isBanned()) {
                bannedIPs.insert(m.ip, m.ban_expire_time);
                bannedMembers.insert(m.name.toLower(), std::pair<QString, int>(m.ip, m.ban_expire_time));
            }
            if (m.authority() > 0) {
                authed.insert(m.name);
            }
            playersByIp.insert(m.ip, m.name);
        }
        lastPlace = memberFile.pos();
    }

    //We also clean up the file by rewritting it with only the valid contents
    QFile temp (backup);
    if (!temp.open(QFile::WriteOnly | QFile::Truncate))
        throw QObject::tr("Impossible to change %1").arg(backup);

    pos = temp.pos();

    for(auto it = members.begin(); it != members.end(); ++it) {
        Member &m = it->second;
        m.write(&temp);
        m.filepos = pos;
        pos = temp.pos();
    }

    lastPlace = temp.pos();

    temp.flush();
    memberFile.remove();

    if (!temp.rename(path)) {
        throw QObject::tr("Error: cannot rename the file that contains the members (%1 -> %2)").arg(backup).arg(path);
    }

    temp.rename(path);

    if (!memberFile.open(QFile::ReadWrite)) {
        throw QObject::tr("Error: cannot reopen the file that contains the members (%1)").arg(path);
    }
}