Automatically fix desynced demo files with issues pre-#496 PR (#532)

* Implement a demo auto-fixing solution. If the client detects a pre-2.9.1 demo file, it will prompt the user if they wish to correct it, since otherwise the demo will be desynched from reality.
The aforementioned issue was fixed in https://github.com/AttorneyOnline/AO2-Client/pull/496 however 2.9.0 still has incorrect demo recording.
Fix potential memory leak by not flushing and closing the demo file after opening it for reading.

* backup broken demo file before fixing it

* comments ahoy

Co-authored-by: in1tiate <radwoodward@vikings.grayson.edu>
This commit is contained in:
Crystalwarrior 2021-04-23 09:55:04 +03:00 committed by GitHub
parent 3e4de5da62
commit 9fbe899c0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 0 deletions

View File

@ -10,6 +10,7 @@
#include <QTcpSocket>
#include <QTimer>
#include <QFileDialog>
#include <QMessageBox>
class DemoServer : public QObject
{

View File

@ -252,6 +252,56 @@ void DemoServer::load_demo(QString filename)
demo_data.enqueue(line);
line = demo_stream.readLine();
}
demo_file.flush();
demo_file.close();
// No-shenanigans 2.9.0 demo file with the dreaded demo desync bug detected https://github.com/AttorneyOnline/AO2-Client/pull/496
// If we don't start with the SC packet this means user-edited weirdo shenanigans. Don't screw around with those.
if (demo_data.head().startsWith("SC#") && demo_data.last().startsWith("wait#")) {
qDebug() << "Loaded a broken pre-2.9.1 demo file, with the wait desync issue!";
QMessageBox *msgBox = new QMessageBox;
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setTextFormat(Qt::RichText);
msgBox->setText("This appears to be a <b>broken</b> pre-2.9.1 demo file with the <a href=https://github.com/AttorneyOnline/AO2-Client/pull/496>wait desync issue</a>!<br>Do you want to correct this file? <i>If you refuse, this demo will be desynchronized!</i>");
msgBox->setWindowTitle("Pre-2.9.1 demo detected!");
msgBox->setStandardButtons(QMessageBox::NoButton);
QTimer::singleShot(2000, msgBox, std::bind(&QMessageBox::setStandardButtons,msgBox,QMessageBox::Yes|QMessageBox::No));
int ret = msgBox->exec();
QQueue <QString> p_demo_data;
switch (ret) {
case QMessageBox::Yes:
qDebug() << "Making a backup of the broken demo...";
QFile::copy(filename, filename + ".backup");
while (!demo_data.isEmpty()) {
QString current_packet = demo_data.dequeue();
// TODO: faster way of doing this, maybe with QtConcurrent's MapReduce methods?
if (!current_packet.startsWith("SC#") && current_packet.startsWith("wait#")) {
p_demo_data.insert(qMax(1, p_demo_data.size()-1), current_packet);
continue;
}
p_demo_data.enqueue(current_packet);
}
if (demo_file.open(QIODevice::WriteOnly | QIODevice::Text |
QIODevice::Truncate)) {
QTextStream out(&demo_file);
out.setCodec("UTF-8");
out << p_demo_data.dequeue();
for (QString line : p_demo_data) {
out << "\n" << line;
}
demo_file.flush();
demo_file.close();
}
load_demo(filename);
break;
case QMessageBox::No:
// No was clicked
break;
default:
// should never be reached
break;
}
}
}
void DemoServer::playback()