Don't do failover for Android, try reconnecting automatically once
Issue: AOTextArea is supposed to have red text for errors, but it's not working
This commit is contained in:
parent
d93a558ae7
commit
a8ccbe77c1
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,3 +5,5 @@
|
|||||||
*.so
|
*.so
|
||||||
base_override.h
|
base_override.h
|
||||||
|
|
||||||
|
base-full/
|
||||||
|
bass.lib
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv)
|
AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv)
|
||||||
{
|
{
|
||||||
net_manager = new NetworkManager(this);
|
net_manager = new NetworkManager(this);
|
||||||
QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool)), SLOT(ms_connect_finished(bool)));
|
QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool, bool)),
|
||||||
|
SLOT(ms_connect_finished(bool, bool)));
|
||||||
}
|
}
|
||||||
|
|
||||||
AOApplication::~AOApplication()
|
AOApplication::~AOApplication()
|
||||||
@ -136,7 +137,7 @@ void AOApplication::loading_cancelled()
|
|||||||
w_lobby->hide_loading_overlay();
|
w_lobby->hide_loading_overlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOApplication::ms_connect_finished(bool connected)
|
void AOApplication::ms_connect_finished(bool connected, bool will_retry)
|
||||||
{
|
{
|
||||||
if (connected)
|
if (connected)
|
||||||
{
|
{
|
||||||
@ -145,10 +146,18 @@ void AOApplication::ms_connect_finished(bool connected)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
call_error("There was an error connecting to the master server.\n"
|
if (will_retry)
|
||||||
"We deploy multiple master servers to mitigate any possible downtime,"
|
{
|
||||||
"but the client appears to have exhausted all possible methods of finding"
|
w_lobby->append_error("Error connecting to master server. Will try again in "
|
||||||
"and connecting to one.\n"
|
+ QString::number(net_manager->ms_reconnect_delay_ms / 1000.f) + " seconds.");
|
||||||
"Please check your Internet connection and firewall, and please try again.");
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
call_error("There was an error connecting to the master server.\n"
|
||||||
|
"We deploy multiple master servers to mitigate any possible downtime, "
|
||||||
|
"but the client appears to have exhausted all possible methods of finding "
|
||||||
|
"and connecting to one.\n"
|
||||||
|
"Please check your Internet connection and firewall, and please try again.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ private:
|
|||||||
QVector<server_type> favorite_list;
|
QVector<server_type> favorite_list;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void ms_connect_finished(bool connected);
|
void ms_connect_finished(bool connected, bool will_retry);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void server_disconnected();
|
void server_disconnected();
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
AOTextArea::AOTextArea(QWidget *p_parent) : QTextBrowser(p_parent)
|
AOTextArea::AOTextArea(QWidget *p_parent) : QTextBrowser(p_parent)
|
||||||
{
|
{
|
||||||
|
this->setStyleSheet(".error {color: #0f0}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOTextArea::append_chatmessage(QString p_name, QString p_message)
|
void AOTextArea::append_chatmessage(QString p_name, QString p_message)
|
||||||
@ -21,81 +21,37 @@ void AOTextArea::append_chatmessage(QString p_name, QString p_message)
|
|||||||
this->append("");
|
this->append("");
|
||||||
this->insertHtml("<b>" + p_name.toHtmlEscaped() + "</b>: ");
|
this->insertHtml("<b>" + p_name.toHtmlEscaped() + "</b>: ");
|
||||||
|
|
||||||
//QRegExp regExp("((([A-Za-z]{3,9}:(?:\\/\\/)?)(?:[\\-;:&=\\+\\$,\\w]+@)?[A-Za-z0-9\\.\\-]+|(?:www\\.|[\\-;:&=\\+\\$,\\w]+@)[A-Za-z0-9\\.\\-]+)((?:\\/[\\+~%\\/\\.\\w\\-]*)?\\??(?:[\\-\\+=&;%@\\.\\w]*)#?(?:[\\.\\!\\/\\\\\\w]*))?)");
|
|
||||||
|
|
||||||
QRegExp omnis_dank_url_regex("\\b(https?://\\S+\\.\\S+)\\b");
|
|
||||||
|
|
||||||
//cheap workarounds ahoy
|
//cheap workarounds ahoy
|
||||||
p_message += " ";
|
p_message += " ";
|
||||||
QString result = p_message.toHtmlEscaped().replace("\n", "<br>").replace(omnis_dank_url_regex, "<a href='\\1'>\\1</a>" );
|
QString result = p_message.toHtmlEscaped().replace("\n", "<br>").replace(omnis_dank_url_regex, "<a href='\\1'>\\1</a>" );
|
||||||
|
|
||||||
this->insertHtml(result);
|
this->insertHtml(result);
|
||||||
|
|
||||||
|
this->auto_scroll(old_cursor, old_scrollbar_value, is_scrolled_down);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
void AOTextArea::append_error(QString p_message)
|
||||||
QRegExp rx("\\bhttp://\\S+");
|
{
|
||||||
|
const QTextCursor old_cursor = this->textCursor();
|
||||||
|
const int old_scrollbar_value = this->verticalScrollBar()->value();
|
||||||
|
const bool is_scrolled_down = old_scrollbar_value == this->verticalScrollBar()->maximum();
|
||||||
|
|
||||||
int first_index = rx.indexIn(p_message);
|
this->moveCursor(QTextCursor::End);
|
||||||
|
|
||||||
qDebug() << "number of rx indices: " << rx.captureCount();
|
this->append("");
|
||||||
|
this->insertHtml("<div class='error'>");
|
||||||
|
|
||||||
if (first_index < 0)
|
p_message += " ";
|
||||||
{
|
QString result = p_message.replace("\n", "<br>").replace(omnis_dank_url_regex, "<a href='\\1'>\\1</a>" );
|
||||||
this->insertPlainText(p_message);
|
|
||||||
qDebug() << "NO REGEX MATCHES";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//indices where we found a regex match
|
this->insertHtml(result);
|
||||||
QVector<int> rx_indices;
|
this->insertHtml("</div>");
|
||||||
QStringList links = rx.capturedTexts();
|
|
||||||
|
|
||||||
qDebug() << "link size" << links.size();
|
this->auto_scroll(old_cursor, old_scrollbar_value, is_scrolled_down);
|
||||||
|
}
|
||||||
rx_indices.append(first_index);
|
|
||||||
|
|
||||||
|
|
||||||
//start at one because first_index is already appended
|
|
||||||
for (int n_pos = 1 ; n_pos < rx.captureCount() ; ++n_pos)
|
|
||||||
rx_indices.append(rx.indexIn(p_message));
|
|
||||||
|
|
||||||
for (int msg_pos = 0 ; msg_pos < p_message.size() ; ++msg_pos)
|
|
||||||
{
|
|
||||||
int tag_index = rx_indices.indexOf(msg_pos);
|
|
||||||
if (tag_index < 0)
|
|
||||||
{
|
|
||||||
this->insertPlainText(p_message.at(msg_pos));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString link = links.at(tag_index);
|
|
||||||
QString html_string = "<a href=\"" + link + "\">" + link + "</a>";
|
|
||||||
qDebug() << "html: " << html_string;
|
|
||||||
|
|
||||||
this->insertHtml(html_string);
|
|
||||||
|
|
||||||
msg_pos += link.size() - 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
QStringList word_list = p_message.split(" ");
|
|
||||||
|
|
||||||
for (QString i_word : word_list)
|
|
||||||
{
|
|
||||||
if (i_word.startsWith("http"))
|
|
||||||
{
|
|
||||||
i_word.replace("\n", "").replace("\r", "");
|
|
||||||
this->insertHtml("<a href=\"" + i_word + "\">" + i_word + "</a> ");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
this->insertPlainText(i_word + " ");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
void AOTextArea::auto_scroll(QTextCursor old_cursor, int old_scrollbar_value, bool is_scrolled_down)
|
||||||
|
{
|
||||||
if (old_cursor.hasSelection() || !is_scrolled_down)
|
if (old_cursor.hasSelection() || !is_scrolled_down)
|
||||||
{
|
{
|
||||||
// The user has selected text or scrolled away from the bottom: maintain position.
|
// The user has selected text or scrolled away from the bottom: maintain position.
|
||||||
|
@ -9,6 +9,12 @@ public:
|
|||||||
AOTextArea(QWidget *p_parent = nullptr);
|
AOTextArea(QWidget *p_parent = nullptr);
|
||||||
|
|
||||||
void append_chatmessage(QString p_name, QString p_message);
|
void append_chatmessage(QString p_name, QString p_message);
|
||||||
|
void append_error(QString p_message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const QRegExp omnis_dank_url_regex = QRegExp("\\b(https?://\\S+\\.\\S+)\\b");
|
||||||
|
|
||||||
|
void auto_scroll(QTextCursor old_cursor, int scrollbar_value, bool is_scrolled_down);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AOTEXTAREA_H
|
#endif // AOTEXTAREA_H
|
||||||
|
@ -262,8 +262,9 @@ void Lobby::on_about_clicked()
|
|||||||
call_notice("Attorney Online 2 is built using Qt 5.7\n\n"
|
call_notice("Attorney Online 2 is built using Qt 5.7\n\n"
|
||||||
"Lead development:\n"
|
"Lead development:\n"
|
||||||
"OmniTroid\n\n"
|
"OmniTroid\n\n"
|
||||||
"Supporting development:\n"
|
|
||||||
"stonedDiscord\n"
|
"stonedDiscord\n"
|
||||||
|
"longbyte1\n"
|
||||||
|
"Supporting development:\n"
|
||||||
"Fiercy\n\n"
|
"Fiercy\n\n"
|
||||||
"UI design:\n"
|
"UI design:\n"
|
||||||
"Ruekasu\n"
|
"Ruekasu\n"
|
||||||
@ -357,6 +358,11 @@ void Lobby::append_chatmessage(QString f_name, QString f_message)
|
|||||||
ui_chatbox->append_chatmessage(f_name, f_message);
|
ui_chatbox->append_chatmessage(f_name, f_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lobby::append_error(QString f_message)
|
||||||
|
{
|
||||||
|
ui_chatbox->append_error(f_message);
|
||||||
|
}
|
||||||
|
|
||||||
void Lobby::set_player_count(int players_online, int max_players)
|
void Lobby::set_player_count(int players_online, int max_players)
|
||||||
{
|
{
|
||||||
QString f_string = "Online: " + QString::number(players_online) + "/" + QString::number(max_players);
|
QString f_string = "Online: " + QString::number(players_online) + "/" + QString::number(max_players);
|
||||||
|
1
lobby.h
1
lobby.h
@ -27,6 +27,7 @@ public:
|
|||||||
void list_servers();
|
void list_servers();
|
||||||
void list_favorites();
|
void list_favorites();
|
||||||
void append_chatmessage(QString f_name, QString f_message);
|
void append_chatmessage(QString f_name, QString f_message);
|
||||||
|
void append_error(QString f_message);
|
||||||
void set_player_count(int players_online, int max_players);
|
void set_player_count(int players_online, int max_players);
|
||||||
void set_loading_text(QString p_text);
|
void set_loading_text(QString p_text);
|
||||||
void show_loading_overlay(){ui_loading_background->show();}
|
void show_loading_overlay(){ui_loading_background->show();}
|
||||||
|
@ -12,6 +12,10 @@ NetworkManager::NetworkManager(AOApplication *parent) : QObject(parent)
|
|||||||
ms_socket = new QTcpSocket(this);
|
ms_socket = new QTcpSocket(this);
|
||||||
server_socket = new QTcpSocket(this);
|
server_socket = new QTcpSocket(this);
|
||||||
|
|
||||||
|
ms_reconnect_timer = new QTimer(this);
|
||||||
|
ms_reconnect_timer->setSingleShot(true);
|
||||||
|
QObject::connect(ms_reconnect_timer, SIGNAL(timeout()), this, SLOT(retry_ms_connect()));
|
||||||
|
|
||||||
QObject::connect(ms_socket, SIGNAL(readyRead()), this, SLOT(handle_ms_packet()));
|
QObject::connect(ms_socket, SIGNAL(readyRead()), this, SLOT(handle_ms_packet()));
|
||||||
QObject::connect(server_socket, SIGNAL(readyRead()), this, SLOT(handle_server_packet()));
|
QObject::connect(server_socket, SIGNAL(readyRead()), this, SLOT(handle_server_packet()));
|
||||||
QObject::connect(server_socket, SIGNAL(disconnected()), ao_app, SLOT(server_disconnected()));
|
QObject::connect(server_socket, SIGNAL(disconnected()), ao_app, SLOT(server_disconnected()));
|
||||||
@ -27,7 +31,16 @@ void NetworkManager::connect_to_master()
|
|||||||
ms_socket->close();
|
ms_socket->close();
|
||||||
ms_socket->abort();
|
ms_socket->abort();
|
||||||
|
|
||||||
|
#ifdef MS_FAILOVER_SUPPORTED
|
||||||
perform_srv_lookup();
|
perform_srv_lookup();
|
||||||
|
#else
|
||||||
|
QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||||
|
this, SLOT(on_ms_connect_error(QAbstractSocket::SocketError)));
|
||||||
|
|
||||||
|
QObject::connect(ms_socket, SIGNAL(connected()),
|
||||||
|
this, SLOT(on_ms_nosrv_connect_success()));
|
||||||
|
ms_socket->connectToHost(ms_nosrv_hostname, ms_port);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkManager::connect_to_server(server_type p_server)
|
void NetworkManager::connect_to_server(server_type p_server)
|
||||||
@ -40,7 +53,14 @@ void NetworkManager::connect_to_server(server_type p_server)
|
|||||||
|
|
||||||
void NetworkManager::ship_ms_packet(QString p_packet)
|
void NetworkManager::ship_ms_packet(QString p_packet)
|
||||||
{
|
{
|
||||||
ms_socket->write(p_packet.toUtf8());
|
if (!ms_socket->isOpen())
|
||||||
|
{
|
||||||
|
retry_ms_connect();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ms_socket->write(p_packet.toUtf8());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkManager::ship_server_packet(QString p_packet)
|
void NetworkManager::ship_server_packet(QString p_packet)
|
||||||
@ -82,9 +102,10 @@ void NetworkManager::handle_ms_packet()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MS_FAILOVER_SUPPORTED
|
||||||
void NetworkManager::perform_srv_lookup()
|
void NetworkManager::perform_srv_lookup()
|
||||||
{
|
{
|
||||||
ms_dns = new QDnsLookup(QDnsLookup::SRV, ms_hostname, this);
|
ms_dns = new QDnsLookup(QDnsLookup::SRV, ms_srv_hostname, this);
|
||||||
|
|
||||||
connect(ms_dns, SIGNAL(finished()), this, SLOT(on_srv_lookup()));
|
connect(ms_dns, SIGNAL(finished()), this, SLOT(on_srv_lookup()));
|
||||||
ms_dns->lookup();
|
ms_dns->lookup();
|
||||||
@ -127,7 +148,13 @@ void NetworkManager::on_srv_lookup()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (timer.elapsed() < timeout_milliseconds); // Very expensive spin-wait loop - it will bring CPU to 100%!
|
} while (timer.elapsed() < timeout_milliseconds); // Very expensive spin-wait loop - it will bring CPU to 100%!
|
||||||
if (connected) break;
|
if (connected)
|
||||||
|
{
|
||||||
|
// Connect a one-shot signal in case the master server disconnects randomly
|
||||||
|
QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||||
|
this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ms_socket->abort();
|
ms_socket->abort();
|
||||||
@ -135,7 +162,37 @@ void NetworkManager::on_srv_lookup()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit ms_connect_finished(connected);
|
emit ms_connect_finished(connected, false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void NetworkManager::on_ms_nosrv_connect_success()
|
||||||
|
{
|
||||||
|
emit ms_connect_finished(true, false);
|
||||||
|
|
||||||
|
QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||||
|
this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkManager::on_ms_socket_error(QAbstractSocket::SocketError error)
|
||||||
|
{
|
||||||
|
qWarning() << "Master server socket error:" << ms_socket->errorString()
|
||||||
|
<< "(" << error << ")";
|
||||||
|
|
||||||
|
// Disconnect the one-shot signal - this way, failover connect attempts
|
||||||
|
// don't trigger a full retry
|
||||||
|
QObject::disconnect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||||
|
this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError)));
|
||||||
|
|
||||||
|
emit ms_connect_finished(false, true);
|
||||||
|
|
||||||
|
ms_reconnect_timer->start(ms_reconnect_delay_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkManager::retry_ms_connect()
|
||||||
|
{
|
||||||
|
if (!ms_reconnect_timer->isActive() && ms_socket->state() != QAbstractSocket::ConnectingState)
|
||||||
|
connect_to_master();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkManager::handle_server_packet()
|
void NetworkManager::handle_server_packet()
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
#ifndef NETWORKMANAGER_H
|
#ifndef NETWORKMANAGER_H
|
||||||
#define NETWORKMANAGER_H
|
#define NETWORKMANAGER_H
|
||||||
|
|
||||||
|
// Qt for Android has stubbed QDnsLookup. This is not documented in any part of their wiki.
|
||||||
|
// This prevents SRV lookup/failover behavior from functioning.
|
||||||
|
// https://bugreports.qt.io/browse/QTBUG-56143
|
||||||
|
#ifndef ANDROID
|
||||||
|
#define MS_FAILOVER_SUPPORTED
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "aopacket.h"
|
#include "aopacket.h"
|
||||||
#include "aoapplication.h"
|
#include "aoapplication.h"
|
||||||
|
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
#include <QDnsLookup>
|
#include <QDnsLookup>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
class NetworkManager : public QObject
|
class NetworkManager : public QObject
|
||||||
{
|
{
|
||||||
@ -20,11 +28,16 @@ public:
|
|||||||
QTcpSocket *ms_socket;
|
QTcpSocket *ms_socket;
|
||||||
QTcpSocket *server_socket;
|
QTcpSocket *server_socket;
|
||||||
QDnsLookup *ms_dns;
|
QDnsLookup *ms_dns;
|
||||||
|
QTimer *ms_reconnect_timer;
|
||||||
|
|
||||||
QString ms_hostname = "_aoms._tcp.aceattorneyonline.com";
|
const QString ms_srv_hostname = "_aoms._tcp.aceattorneyonline.com";
|
||||||
int ms_port = 27016;
|
const QString ms_nosrv_hostname = "master.aceattorneyonline.com";
|
||||||
|
|
||||||
|
const int ms_port = 27016;
|
||||||
const int timeout_milliseconds = 2000;
|
const int timeout_milliseconds = 2000;
|
||||||
|
|
||||||
|
const int ms_reconnect_delay_ms = 5000;
|
||||||
|
|
||||||
bool ms_partial_packet = false;
|
bool ms_partial_packet = false;
|
||||||
QString ms_temp_packet = "";
|
QString ms_temp_packet = "";
|
||||||
|
|
||||||
@ -41,7 +54,7 @@ public slots:
|
|||||||
void ship_server_packet(QString p_packet);
|
void ship_server_packet(QString p_packet);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ms_connect_finished(bool success);
|
void ms_connect_finished(bool success, bool will_retry);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void perform_srv_lookup();
|
void perform_srv_lookup();
|
||||||
@ -50,6 +63,9 @@ private slots:
|
|||||||
void on_srv_lookup();
|
void on_srv_lookup();
|
||||||
void handle_ms_packet();
|
void handle_ms_packet();
|
||||||
void handle_server_packet();
|
void handle_server_packet();
|
||||||
|
void on_ms_nosrv_connect_success();
|
||||||
|
void on_ms_socket_error(QAbstractSocket::SocketError error);
|
||||||
|
void retry_ms_connect();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NETWORKMANAGER_H
|
#endif // NETWORKMANAGER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user