Dual-Stack AO2 Client to handle both TCP and Websocket connections seemlessly (#696)
* Replace TCP Serversocket with Websocket * Have TCP sockets live harmoniously with WS "like 5 lines" yeah probably lost a bet. * Update .gitlab-ci.yml * hack to fix favorites * Add support for websockets in the favorites list (serverlist.txt) Make "add_favorite_server" remember the socket type * Preserve old serverlist style This will keep new entries compatible with 2.9 and prior clients. Makes parsing the list easier too. * Add lookup table and correct write code to use lowercase * I have no idea what a lookup table is, but this looks close enough * Fix lookup table * Otherwise backend selection behaviour is inverted * clang-tidy had one job * Yet it did not do it. Co-authored-by: oldmud0 <oldmud0@users.noreply.github.com> * const p_data * Switch serverlist.txt to an ini format * Fixes an Omni bug where : would split the servername * Utilises internally QSettings properly for low parsing effort and clear structure * Automatically migrates the legacy serverlist.txt to favorite_servers.ini * Pleases my OCD * Replace sample serverlist. Co-authored-by: oldmud0 <oldmud0@users.noreply.github.com> Co-authored-by: stonedDiscord <Tukz@gmx.de> Co-authored-by: Alex Noir <Varsash@gmail.com>
This commit is contained in:
		
							parent
							
								
									c4f459b6cc
								
							
						
					
					
						commit
						f0a5e48f5c
					
				@ -1,4 +1,4 @@
 | 
			
		||||
QT += core gui widgets network
 | 
			
		||||
QT += core gui widgets network websockets
 | 
			
		||||
 | 
			
		||||
TARGET = Attorney_Online
 | 
			
		||||
TEMPLATE = app
 | 
			
		||||
 | 
			
		||||
@ -31,10 +31,10 @@ endif()
 | 
			
		||||
target_include_directories(Attorney_Online PRIVATE include)
 | 
			
		||||
 | 
			
		||||
# Target Lib
 | 
			
		||||
find_package(Qt5 COMPONENTS Core Gui Network Widgets Concurrent REQUIRED)
 | 
			
		||||
find_package(Qt5 COMPONENTS Core Gui Network Widgets Concurrent WebSockets REQUIRED)
 | 
			
		||||
target_link_directories(Attorney_Online PRIVATE lib)
 | 
			
		||||
target_link_libraries(Attorney_Online PRIVATE Qt5::Core Qt5::Gui Qt5::Network Qt5::Widgets Qt5::Concurrent
 | 
			
		||||
    bass bassmidi bassopus discord-rpc)
 | 
			
		||||
    Qt5::WebSockets bass bassmidi bassopus discord-rpc)
 | 
			
		||||
target_compile_definitions(Attorney_Online PRIVATE DISCORD)
 | 
			
		||||
 | 
			
		||||
# Subdirectories
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								base/favorite_servers_sample.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								base/favorite_servers_sample.ini
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
[0]
 | 
			
		||||
name=Default Local Server
 | 
			
		||||
address=127.0.0.1
 | 
			
		||||
port=27016
 | 
			
		||||
protocol=tcp
 | 
			
		||||
@ -1 +0,0 @@
 | 
			
		||||
127.0.0.1:27016:Default local server
 | 
			
		||||
@ -133,6 +133,8 @@ public:
 | 
			
		||||
 | 
			
		||||
  void set_favorite_list();
 | 
			
		||||
  QVector<server_type> &get_favorite_list() { return favorite_list; }
 | 
			
		||||
 | 
			
		||||
  // Adds the server to favorite_servers.ini
 | 
			
		||||
  void add_favorite_server(int p_server);
 | 
			
		||||
 | 
			
		||||
  void set_server_list(QVector<server_type> &servers) { server_list = servers; }
 | 
			
		||||
@ -324,12 +326,14 @@ public:
 | 
			
		||||
  // Append to the currently open demo file if there is one
 | 
			
		||||
  void append_to_demofile(QString packet_string);
 | 
			
		||||
 | 
			
		||||
  // Appends the argument string to serverlist.txt
 | 
			
		||||
  void write_to_serverlist_txt(QString p_line);
 | 
			
		||||
 | 
			
		||||
  // Returns the contents of serverlist.txt
 | 
			
		||||
  QVector<server_type> read_serverlist_txt();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @brief Migrates the favorite serverlist format from txt to ini.
 | 
			
		||||
   */
 | 
			
		||||
  void migrate_serverlist_txt(QFile &p_serverlist_txt);
 | 
			
		||||
 | 
			
		||||
  // Returns the value of p_identifier in the design.ini file in p_design_path
 | 
			
		||||
  QString read_design_ini(QString p_identifier, VPath p_design_path);
 | 
			
		||||
  QString read_design_ini(QString p_identifier, QString p_design_path);
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,25 @@
 | 
			
		||||
#ifndef DATATYPES_H
 | 
			
		||||
#define DATATYPES_H
 | 
			
		||||
 | 
			
		||||
#include <QMap>
 | 
			
		||||
#include <QString>
 | 
			
		||||
 | 
			
		||||
enum connection_type {
 | 
			
		||||
  TCP,
 | 
			
		||||
  WEBSOCKETS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QMap<QString, connection_type> to_connection_type = {
 | 
			
		||||
    {"tcp", connection_type::TCP},
 | 
			
		||||
    {"ws", connection_type::WEBSOCKETS}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct server_type {
 | 
			
		||||
  QString name;
 | 
			
		||||
  QString desc;
 | 
			
		||||
  QString ip;
 | 
			
		||||
  int port;
 | 
			
		||||
  connection_type socket_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct emote_type {
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@
 | 
			
		||||
 | 
			
		||||
#include <QDnsLookup>
 | 
			
		||||
#include <QNetworkAccessManager>
 | 
			
		||||
#include <QTcpSocket>
 | 
			
		||||
#include <QtWebSockets/QWebSocket>
 | 
			
		||||
#include <QTime>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
 | 
			
		||||
@ -21,16 +21,20 @@ enum MSDocumentType {
 | 
			
		||||
class NetworkManager : public QObject {
 | 
			
		||||
  Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  explicit NetworkManager(AOApplication *parent);
 | 
			
		||||
  ~NetworkManager() = default;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  AOApplication *ao_app;
 | 
			
		||||
  QNetworkAccessManager *http;
 | 
			
		||||
  QTcpSocket *server_socket;
 | 
			
		||||
 | 
			
		||||
  union {
 | 
			
		||||
    QWebSocket *ws;
 | 
			
		||||
    QTcpSocket *tcp;
 | 
			
		||||
  } server_socket;
 | 
			
		||||
  connection_type active_connection_type;
 | 
			
		||||
  bool connected = false;
 | 
			
		||||
 | 
			
		||||
  QTimer *heartbeat_timer;
 | 
			
		||||
 | 
			
		||||
  const QString DEFAULT_MS_BASEURL = "https://servers.aceattorneyonline.com";
 | 
			
		||||
  const QString DEFAULT_MS_BASEURL = "http://servers.aceattorneyonline.com";
 | 
			
		||||
  QString ms_baseurl = DEFAULT_MS_BASEURL;
 | 
			
		||||
 | 
			
		||||
  const int heartbeat_interval = 60 * 5 * 1000;
 | 
			
		||||
@ -40,12 +44,17 @@ public:
 | 
			
		||||
 | 
			
		||||
  unsigned int s_decryptor = 5;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  explicit NetworkManager(AOApplication *parent);
 | 
			
		||||
  ~NetworkManager() = default;
 | 
			
		||||
 | 
			
		||||
  void connect_to_server(server_type p_server);
 | 
			
		||||
  void disconnect_from_server();
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
  void get_server_list(const std::function<void()> &cb);
 | 
			
		||||
  void ship_server_packet(QString p_packet);
 | 
			
		||||
  void handle_server_packet();
 | 
			
		||||
  void handle_server_packet(const QString& p_data);
 | 
			
		||||
 | 
			
		||||
  void request_document(MSDocumentType document_type,
 | 
			
		||||
                        const std::function<void(QString)> &cb);
 | 
			
		||||
 | 
			
		||||
@ -144,12 +144,22 @@ void AOApplication::add_favorite_server(int p_server)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  server_type fav_server = server_list.at(p_server);
 | 
			
		||||
  QSettings l_favorite_ini(get_base_path() + "favorite_servers.ini", QSettings::IniFormat);
 | 
			
		||||
  QString l_new_group = QString::number(l_favorite_ini.childGroups().size());
 | 
			
		||||
  l_favorite_ini.setIniCodec("UTF-8");
 | 
			
		||||
 | 
			
		||||
  QString str_port = QString::number(fav_server.port);
 | 
			
		||||
  l_favorite_ini.beginGroup(l_new_group);
 | 
			
		||||
  l_favorite_ini.setValue("name", fav_server.name);
 | 
			
		||||
  l_favorite_ini.setValue("address", fav_server.ip);
 | 
			
		||||
  l_favorite_ini.setValue("port", fav_server.port);
 | 
			
		||||
 | 
			
		||||
  QString server_line = fav_server.ip + ":" + str_port + ":" + fav_server.name;
 | 
			
		||||
 | 
			
		||||
  write_to_serverlist_txt(server_line);
 | 
			
		||||
  if (fav_server.socket_type == TCP) {
 | 
			
		||||
   l_favorite_ini.setValue("protocol", "tcp");
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    l_favorite_ini.setValue("protocol", "ws");
 | 
			
		||||
  }
 | 
			
		||||
  l_favorite_ini.sync();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AOApplication::server_disconnected()
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@
 | 
			
		||||
#include "debug_functions.h"
 | 
			
		||||
#include "lobby.h"
 | 
			
		||||
 | 
			
		||||
#include <QAbstractSocket>
 | 
			
		||||
#include <QJsonArray>
 | 
			
		||||
#include <QJsonDocument>
 | 
			
		||||
#include <QNetworkReply>
 | 
			
		||||
@ -12,15 +13,9 @@ NetworkManager::NetworkManager(AOApplication *parent) : QObject(parent)
 | 
			
		||||
{
 | 
			
		||||
  ao_app = parent;
 | 
			
		||||
 | 
			
		||||
  server_socket = new QTcpSocket(this);
 | 
			
		||||
  http = new QNetworkAccessManager(this);
 | 
			
		||||
  heartbeat_timer = new QTimer(this);
 | 
			
		||||
 | 
			
		||||
  connect(server_socket, &QTcpSocket::readyRead, this,
 | 
			
		||||
          &NetworkManager::handle_server_packet);
 | 
			
		||||
  connect(server_socket, &QTcpSocket::disconnected, ao_app,
 | 
			
		||||
          &AOApplication::server_disconnected);
 | 
			
		||||
 | 
			
		||||
  QString master_config =
 | 
			
		||||
      ao_app->configini->value("master", "").value<QString>();
 | 
			
		||||
  if (!master_config.isEmpty() && QUrl(master_config).scheme().startsWith("http")) {
 | 
			
		||||
@ -60,10 +55,18 @@ void NetworkManager::ms_request_finished(QNetworkReply *reply,
 | 
			
		||||
    const auto entry = entryRef.toObject();
 | 
			
		||||
    server_type server;
 | 
			
		||||
    server.ip = entry["ip"].toString();
 | 
			
		||||
    server.port = entry["port"].toInt();
 | 
			
		||||
    server.name = entry["name"].toString();
 | 
			
		||||
    server.desc = entry["description"].toString(tr("No description provided."));
 | 
			
		||||
    server_list.append(server);
 | 
			
		||||
    if (entry["ws_port"].isDouble()) {
 | 
			
		||||
      server.socket_type = WEBSOCKETS;
 | 
			
		||||
      server.port = entry["ws_port"].toInt();
 | 
			
		||||
    } else {
 | 
			
		||||
      server.socket_type = TCP;
 | 
			
		||||
      server.port = entry["port"].toInt();
 | 
			
		||||
    }
 | 
			
		||||
    if (server.port != 0) {
 | 
			
		||||
        server_list.append(server);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  ao_app->set_server_list(server_list);
 | 
			
		||||
 | 
			
		||||
@ -128,26 +131,99 @@ void NetworkManager::request_document(MSDocumentType document_type,
 | 
			
		||||
 | 
			
		||||
void NetworkManager::connect_to_server(server_type p_server)
 | 
			
		||||
{
 | 
			
		||||
  server_socket->close();
 | 
			
		||||
  server_socket->abort();
 | 
			
		||||
  disconnect_from_server();
 | 
			
		||||
 | 
			
		||||
  qInfo().nospace().noquote() << "connecting to " << p_server.ip << ":"
 | 
			
		||||
                              << p_server.port;
 | 
			
		||||
 | 
			
		||||
  server_socket->connectToHost(p_server.ip, p_server.port);
 | 
			
		||||
  switch (p_server.socket_type) {
 | 
			
		||||
  default:
 | 
			
		||||
    p_server.socket_type = TCP;
 | 
			
		||||
    [[fallthrough]];
 | 
			
		||||
  case TCP:
 | 
			
		||||
    qInfo() << "using TCP backend";
 | 
			
		||||
    server_socket.tcp = new QTcpSocket(this);
 | 
			
		||||
 | 
			
		||||
    connect(server_socket.tcp, &QAbstractSocket::connected, this, [] {
 | 
			
		||||
      qDebug() << "established connection to server";
 | 
			
		||||
    });
 | 
			
		||||
    connect(server_socket.tcp, &QIODevice::readyRead, this, [this] {
 | 
			
		||||
      handle_server_packet(QString::fromUtf8(server_socket.tcp->readAll()));
 | 
			
		||||
    });
 | 
			
		||||
    connect(server_socket.tcp, &QAbstractSocket::disconnected, ao_app,
 | 
			
		||||
            &AOApplication::server_disconnected);
 | 
			
		||||
    connect(server_socket.tcp, &QAbstractSocket::errorOccurred, this, [this] {
 | 
			
		||||
      qCritical() << "TCP socket error:" << server_socket.tcp->errorString();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    server_socket.tcp->connectToHost(p_server.ip, p_server.port);
 | 
			
		||||
    break;
 | 
			
		||||
  case WEBSOCKETS:
 | 
			
		||||
    qInfo() << "using WebSockets backend";
 | 
			
		||||
    server_socket.ws = new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this);
 | 
			
		||||
 | 
			
		||||
    connect(server_socket.ws, &QWebSocket::connected, this, [] {
 | 
			
		||||
      qDebug() << "established connection to server";
 | 
			
		||||
    });
 | 
			
		||||
    connect(server_socket.ws, &QWebSocket::textMessageReceived, this,
 | 
			
		||||
            &NetworkManager::handle_server_packet);
 | 
			
		||||
    connect(server_socket.ws, &QWebSocket::disconnected, ao_app,
 | 
			
		||||
            &AOApplication::server_disconnected);
 | 
			
		||||
    connect(server_socket.ws, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error),
 | 
			
		||||
            this, [this] {
 | 
			
		||||
      qCritical() << "WebSockets error:" << server_socket.ws->errorString();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    QUrl url;
 | 
			
		||||
    url.setScheme("ws");
 | 
			
		||||
    url.setHost(p_server.ip);
 | 
			
		||||
    url.setPort(p_server.port);
 | 
			
		||||
    QNetworkRequest req(url);
 | 
			
		||||
    req.setHeader(QNetworkRequest::UserAgentHeader, get_user_agent());
 | 
			
		||||
    server_socket.ws->open(req);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  connected = true;
 | 
			
		||||
  active_connection_type = p_server.socket_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NetworkManager::disconnect_from_server()
 | 
			
		||||
{
 | 
			
		||||
  if (!connected)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  switch (active_connection_type) {
 | 
			
		||||
  case TCP:
 | 
			
		||||
    server_socket.tcp->close();
 | 
			
		||||
    server_socket.tcp->deleteLater();
 | 
			
		||||
    break;
 | 
			
		||||
  case WEBSOCKETS:
 | 
			
		||||
    server_socket.ws->close(QWebSocketProtocol::CloseCodeGoingAway);
 | 
			
		||||
    server_socket.ws->deleteLater();
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  connected = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NetworkManager::ship_server_packet(QString p_packet)
 | 
			
		||||
{
 | 
			
		||||
  server_socket->write(p_packet.toUtf8());
 | 
			
		||||
  switch (active_connection_type) {
 | 
			
		||||
  case TCP:
 | 
			
		||||
    server_socket.tcp->write(p_packet.toUtf8());
 | 
			
		||||
    break;
 | 
			
		||||
  case WEBSOCKETS:
 | 
			
		||||
    server_socket.ws->sendTextMessage(p_packet);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NetworkManager::handle_server_packet()
 | 
			
		||||
void NetworkManager::handle_server_packet(const QString& p_data)
 | 
			
		||||
{
 | 
			
		||||
  QByteArray buffer = server_socket->readAll();
 | 
			
		||||
  QString in_data = QString::fromUtf8(buffer, buffer.size());
 | 
			
		||||
  QString in_data = p_data;
 | 
			
		||||
 | 
			
		||||
  if (!in_data.endsWith("%")) {
 | 
			
		||||
  if (!p_data.endsWith("%")) {
 | 
			
		||||
    partial_packet = true;
 | 
			
		||||
    temp_packet += in_data;
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
@ -236,52 +236,30 @@ bool AOApplication::append_to_file(QString p_text, QString p_file,
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AOApplication::write_to_serverlist_txt(QString p_line)
 | 
			
		||||
{
 | 
			
		||||
  QFile serverlist_txt;
 | 
			
		||||
  QString serverlist_txt_path = get_base_path() + "serverlist.txt";
 | 
			
		||||
 | 
			
		||||
  serverlist_txt.setFileName(serverlist_txt_path);
 | 
			
		||||
 | 
			
		||||
  if (!serverlist_txt.open(QIODevice::WriteOnly | QIODevice::Append)) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  QTextStream out(&serverlist_txt);
 | 
			
		||||
  out.setCodec("UTF-8");
 | 
			
		||||
  out << "\r\n" << p_line;
 | 
			
		||||
 | 
			
		||||
  serverlist_txt.close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVector<server_type> AOApplication::read_serverlist_txt()
 | 
			
		||||
{
 | 
			
		||||
  QVector<server_type> f_server_list;
 | 
			
		||||
 | 
			
		||||
  QFile serverlist_txt;
 | 
			
		||||
  QString serverlist_txt_path = get_base_path() + "serverlist.txt";
 | 
			
		||||
  QFile serverlist_txt(get_base_path() + "serverlist.txt");
 | 
			
		||||
  QFile serverlist_ini(get_base_path() + "favorite_servers.ini");
 | 
			
		||||
 | 
			
		||||
  serverlist_txt.setFileName(serverlist_txt_path);
 | 
			
		||||
  if (serverlist_txt.exists() && !serverlist_ini.exists()) {
 | 
			
		||||
    migrate_serverlist_txt(serverlist_txt);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (serverlist_txt.open(QIODevice::ReadOnly)) {
 | 
			
		||||
      QTextStream in(&serverlist_txt);
 | 
			
		||||
      in.setCodec("UTF-8");
 | 
			
		||||
 | 
			
		||||
      while (!in.atEnd()) {
 | 
			
		||||
        QString line = in.readLine();
 | 
			
		||||
        server_type f_server;
 | 
			
		||||
        QStringList line_contents = line.split(":");
 | 
			
		||||
 | 
			
		||||
        if (line_contents.size() < 3)
 | 
			
		||||
          continue;
 | 
			
		||||
 | 
			
		||||
        f_server.ip = line_contents.at(0);
 | 
			
		||||
        f_server.port = line_contents.at(1).toInt();
 | 
			
		||||
        f_server.name = line_contents.at(2);
 | 
			
		||||
        f_server.desc = "";
 | 
			
		||||
 | 
			
		||||
        f_server_list.append(f_server);
 | 
			
		||||
      }
 | 
			
		||||
  if (serverlist_ini.exists()) {
 | 
			
		||||
    QSettings l_favorite_ini(get_base_path() + "favorite_servers.ini", QSettings::IniFormat);
 | 
			
		||||
    l_favorite_ini.setIniCodec("UTF-8");
 | 
			
		||||
    for(QString &fav_index: l_favorite_ini.childGroups()) {
 | 
			
		||||
      server_type f_server;
 | 
			
		||||
      l_favorite_ini.beginGroup(fav_index);
 | 
			
		||||
      f_server.ip = l_favorite_ini.value("address", "127.0.0.1").toString();
 | 
			
		||||
      f_server.port = l_favorite_ini.value("port", 27016).toInt();
 | 
			
		||||
      f_server.name = l_favorite_ini.value("name", "Missing Name").toString();
 | 
			
		||||
      f_server.socket_type = to_connection_type.value(l_favorite_ini.value("protocol", "tcp").toString());
 | 
			
		||||
      f_server_list.append(f_server);
 | 
			
		||||
      l_favorite_ini.endGroup();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  server_type demo_server;
 | 
			
		||||
@ -294,6 +272,43 @@ QVector<server_type> AOApplication::read_serverlist_txt()
 | 
			
		||||
  return f_server_list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AOApplication::migrate_serverlist_txt(QFile &p_serverlist_txt)
 | 
			
		||||
{
 | 
			
		||||
  // We migrate our legacy serverlist.txt to a QSettings object.
 | 
			
		||||
  // Then we write it to disk.
 | 
			
		||||
  QSettings l_settings(get_base_path() + "favorite_servers.ini", QSettings::IniFormat);
 | 
			
		||||
  l_settings.setIniCodec("UTF-8");
 | 
			
		||||
  if (p_serverlist_txt.open(QIODevice::ReadOnly)) {
 | 
			
		||||
    QTextStream l_favorite_textstream(&p_serverlist_txt);
 | 
			
		||||
    l_favorite_textstream.setCodec("UTF-8");
 | 
			
		||||
    int l_entry_index = 0;
 | 
			
		||||
 | 
			
		||||
    while (!l_favorite_textstream.atEnd()) {
 | 
			
		||||
      QString l_favorite_line = l_favorite_textstream.readLine();
 | 
			
		||||
      QStringList l_line_contents = l_favorite_line.split(":");
 | 
			
		||||
 | 
			
		||||
      if (l_line_contents.size() >= 3) {
 | 
			
		||||
        l_settings.beginGroup(QString::number(l_entry_index));
 | 
			
		||||
        l_settings.setValue("name", l_line_contents.at(2));
 | 
			
		||||
        l_settings.setValue("address", l_line_contents.at(0));
 | 
			
		||||
        l_settings.setValue("port", l_line_contents.at(1));
 | 
			
		||||
 | 
			
		||||
        if (l_line_contents.size() >= 4) {
 | 
			
		||||
          l_settings.setValue("protocol", l_line_contents.at(3));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          l_settings.setValue("protocol","tcp");
 | 
			
		||||
        }
 | 
			
		||||
        l_settings.endGroup();
 | 
			
		||||
        l_entry_index++;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    l_settings.sync();
 | 
			
		||||
  }
 | 
			
		||||
  p_serverlist_txt.close();
 | 
			
		||||
  p_serverlist_txt.rename(get_base_path() + "serverlist_depricated.txt");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString AOApplication::read_design_ini(QString p_identifier,
 | 
			
		||||
                                       VPath p_design_path)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user