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); } }