diff options
Diffstat (limited to 'src/demoserver.cpp')
| -rw-r--r-- | src/demoserver.cpp | 148 |
1 files changed, 127 insertions, 21 deletions
diff --git a/src/demoserver.cpp b/src/demoserver.cpp index 88dfdb4b..ee0fcf25 100644 --- a/src/demoserver.cpp +++ b/src/demoserver.cpp @@ -150,7 +150,8 @@ void DemoServer::handle_packet(AOPacket packet) } else if (header == "CC") { client_sock->write("PV#0#CID#-1#%"); - client_sock->write("CT#DEMO#Demo file loaded. Send /play or > in OOC to begin playback.#1#%"); + QString packet = "CT#DEMO#" + tr("Demo file loaded. Send /play or > in OOC to begin playback.") + "#1#%"; + client_sock->write(packet.toUtf8()); } else if (header == "CT") { if (contents[1].startsWith("/load")) @@ -159,14 +160,17 @@ void DemoServer::handle_packet(AOPacket packet) if (path.isEmpty()) return; load_demo(path); - client_sock->write("CT#DEMO#Demo file loaded. Send /play or > in OOC to begin playback.#1#%"); + QString packet = "CT#DEMO#" + tr("Demo file loaded. Send /play or > in OOC to begin playback.") + "#1#%"; + client_sock->write(packet.toUtf8()); + reset_state(); } else if (contents[1].startsWith("/play") || contents[1] == ">") { if (timer->interval() != 0 && !timer->isActive()) { timer->start(); - client_sock->write("CT#DEMO#Resuming playback.#1#%"); + QString packet = "CT#DEMO#" + tr("Resuming playback.") + "#1#%"; + client_sock->write(packet.toUtf8()); } else { @@ -180,7 +184,8 @@ void DemoServer::handle_packet(AOPacket packet) int timeleft = timer->remainingTime(); timer->stop(); timer->setInterval(timeleft); - client_sock->write("CT#DEMO#Pausing playback.#1#%"); + QString packet = "CT#DEMO#" + tr("Pausing playback.") + "#1#%"; + client_sock->write(packet.toUtf8()); } else if (contents[1].startsWith("/max_wait")) { @@ -194,29 +199,44 @@ void DemoServer::handle_packet(AOPacket packet) if (p_max_wait < 0) p_max_wait = -1; max_wait = p_max_wait; - client_sock->write("CT#DEMO#Setting max_wait to "); + QString packet = "CT#DEMO#" + tr("Setting max_wait to") + " "; + client_sock->write(packet.toUtf8()); client_sock->write(QString::number(max_wait).toUtf8()); - client_sock->write(" milliseconds.#1#%"); + packet = " " + tr("milliseconds.") + "#1#%"; + client_sock->write(packet.toUtf8()); } else { - client_sock->write("CT#DEMO#Not a valid integer!#1#%"); + QString packet = "CT#DEMO#" + tr("Not a valid integer!") + "#1#%"; + client_sock->write(packet.toUtf8()); } } else { - client_sock->write("CT#DEMO#Current max_wait is "); - client_sock->write(QString::number(max_wait).toUtf8()); - client_sock->write(" milliseconds.#1#%"); + + QString packet = "CT#DEMO#" + tr("Current max_wait is") + " "; + client_sock->write(packet.toUtf8()); + client_sock->write(QString::number(max_wait).toUtf8()); + packet = " " + tr("milliseconds.") + "#1#%"; + client_sock->write(packet.toUtf8()); } } + else if (contents[1].startsWith("/reload")) + { + load_demo(p_path); + QString packet = "CT#DEMO#" + tr("Current demo file reloaded. Send /play or > in OOC to begin playback.") + "#1#%"; + client_sock->write(packet.toUtf8()); + reset_state(); + } else if (contents[1].startsWith("/min_wait")) { - client_sock->write("CT#DEMO#min_wait is deprecated. Use the client Settings for minimum wait instead!"); + QString packet = "CT#DEMO#" + tr("min_wait is deprecated. Use the client Settings for minimum wait instead!") + "#1#%"; + client_sock->write(packet.toUtf8()); } else if (contents[1].startsWith("/help")) { - client_sock->write("CT#DEMO#Available commands:\nload, play, pause, max_wait, help#1#%"); + QString packet = "CT#DEMO#" + tr("Available commands:\nload, reload, play, pause, max_wait, help") + "#1#%"; + client_sock->write(packet.toUtf8()); } } } @@ -227,18 +247,96 @@ void DemoServer::load_demo(QString filename) demo_file.open(QIODevice::ReadOnly); if (!demo_file.isOpen()) return; + // Clear demo data demo_data.clear(); + // Set the demo filepath p_path = filename; + // Process the demo file QTextStream demo_stream(&demo_file); demo_stream.setCodec("UTF-8"); QString line = demo_stream.readLine(); while (!line.isNull()) { - if (!line.endsWith("%")) { + while (!line.endsWith("%")) { line += "\n"; + line += demo_stream.readLine(); } 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::reset_state() +{ + // Reset evidence list + client_sock->write("LE##%"); + + // Reset timers + client_sock->write("TI#0#3#0#%"); + client_sock->write("TI#0#1#0#%"); + client_sock->write("TI#1#1#0#%"); + client_sock->write("TI#1#3#0#%"); + client_sock->write("TI#2#1#0#%"); + client_sock->write("TI#2#3#0#%"); + client_sock->write("TI#3#1#0#%"); + client_sock->write("TI#3#3#0#%"); + client_sock->write("TI#4#1#0#%"); + client_sock->write("TI#4#3#0#%"); + + // Set the BG to default (also breaks up the message queue) + client_sock->write("BN#default#wit#%"); + + // Stop the wait packet timer + timer->stop(); } void DemoServer::playback() @@ -251,25 +349,33 @@ void DemoServer::playback() if (current_packet.startsWith("MS#")) elapsed_time = 0; - while (!current_packet.startsWith("wait") && !demo_data.isEmpty()) { + while (!current_packet.startsWith("wait#")) { client_sock->write(current_packet.toUtf8()); + if (demo_data.isEmpty()) + break; current_packet = demo_data.dequeue(); } if (!demo_data.isEmpty()) { AOPacket wait_packet = AOPacket(current_packet); int duration = wait_packet.get_contents().at(0).toInt(); - if (max_wait != -1 && duration + elapsed_time > max_wait) { - duration = qMax(0, max_wait - elapsed_time); - // Skip the difference on the timers - emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration); + if (max_wait != -1) { + if (duration + elapsed_time > max_wait) { + duration = qMax(0, max_wait - elapsed_time); + // Skip the difference on the timers + emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration); + } + else if (timer->interval() != 0 && duration + elapsed_time > timer->interval()) { + duration = qMax(0, timer->interval() - elapsed_time); + emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration); + } } elapsed_time += duration; timer->start(duration); } - else - { - client_sock->write("CT#DEMO#Reached the end of the demo file. Send /play or > in OOC to restart, or /load to open a new file.#1#%"); + else { + QString end_packet = "CT#DEMO#" + tr("Reached the end of the demo file. Send /play or > in OOC to restart, or /load to open a new file.") + "#1#%"; + client_sock->write(end_packet.toUtf8()); timer->setInterval(0); } } |
