From 96629d270265f9b75c8c289b7b2ab45ce8f75df3 Mon Sep 17 00:00:00 2001
From: "Dmitriy A. Gerasimov" <dmitriy.gerasimov@demlabs.net>
Date: Sun, 3 Nov 2019 02:27:26 +0700
Subject: [PATCH] [+] DapDataLocal [*] ServersList update

---
 DapDataLocal.cpp          | 217 ++++++++++++++++++++++++++++++++++++++
 DapDataLocal.h            |  72 +++++++++++++
 DapServersListRequester.h |   6 +-
 DapSession.cpp            |  13 +--
 libdap-qt.pri             |   3 +
 5 files changed, 302 insertions(+), 9 deletions(-)
 create mode 100755 DapDataLocal.cpp
 create mode 100755 DapDataLocal.h

diff --git a/DapDataLocal.cpp b/DapDataLocal.cpp
new file mode 100755
index 0000000..e59469f
--- /dev/null
+++ b/DapDataLocal.cpp
@@ -0,0 +1,217 @@
+#include <QStandardPaths>
+
+#include <QXmlStreamReader>
+#include <QDir>
+#include <QFile>
+#include <QtDebug>
+#include <QSettings>
+#include <QCoreApplication>
+#include <algorithm>
+
+#include "DapDataLocal.h"
+
+DapDataLocal::picturesMap DapDataLocal::m_pictruePath = {
+    {DapServerLocation::ENGLAND, ":/country/Flag_uk.png"},
+    {DapServerLocation::FRANCE, ":/country/Flag_fr.png"},
+    {DapServerLocation::GERMANY, ":/country/Flag_de.png"},
+    {DapServerLocation::USA, ":/country/Flag_us.png"},
+    {DapServerLocation::NETHERLANDS, ":/country/Flag_nl.png"},
+    {DapServerLocation::RUSSIA, ":/country/Flag_ru.png"},
+    {DapServerLocation::UKRAINE, ":/country/Flag_ua.png"},
+    {DapServerLocation::UNKNOWN, ":/country/ussr.png"},
+};
+
+DapDataLocal *DapDataLocal::_me = Q_NULLPTR;
+
+DapDataLocal::DapDataLocal()
+{
+    qDebug() << "[DL] Constructor";
+    parseXML(":/data.xml");
+    setServerName(serverTheBest().name);
+}
+
+void DapDataLocal::parseXML(const QString& a_fname)
+{
+    QFile file(a_fname);
+    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
+        qWarning() << "[DL] Can't open data.xml from built in resource";
+        return;
+    }
+
+    QXmlStreamReader *sr = new QXmlStreamReader(&file);
+    if(sr->readNextStartElement()){
+        if(sr->name() == "data"){
+            while ( sr->readNextStartElement() ){
+                if( sr->name() == "servers"){
+                    while ( sr->readNextStartElement() ){
+                        if( sr->name() == "server") {
+                            DapServerInfo item;
+                            while ( sr->readNextStartElement() ){
+                                if(sr->name() == "name"){
+                                    item.name=sr->readElementText();
+                                } else if (sr->name() == "address") {
+                                    item.address=sr->readElementText();
+                                } else if( sr->name() == "port") {
+                                    bool ok;
+                                    quint16 port = quint16(sr->readElementText().toInt(&ok));
+                                    if (!ok) {
+                                        throw std::runtime_error("Can't cast port to int "
+                                                                 "from XML file");
+                                    }
+                                    item.port = port;
+                                } else if(sr->name() == "location") {
+                                    item.location = DapServerInfo::stringToLaction(sr->readElementText());
+                                } else {
+                                    qDebug() << "[DL] Inside tag 'server': Unknown tag "<<sr->name();
+                                    sr->skipCurrentElement();
+                                }
+                            }
+                            qDebug() << "[DL] Server "<<item.name<<" added";
+                            m_servers.push_back(item);
+                        }else{
+                            qDebug() << "[DL] Inside tag 'servers': unknown tag "<<sr->name();
+                            sr->skipCurrentElement();
+                        }
+                    }
+                }else if( sr->name() == "cdb"){
+                    m_cdbServersList = sr->readElementText();
+                }else{
+                    qDebug() << "[DL] Inside tag 'data' unknown tag "<<sr->name();
+                    //sr->skipCurrentElement();
+                }
+            }
+        }
+    }
+#ifdef  QT_DEBUG
+    addServer(DapServerLocation::UNKNOWN, "local", "127.0.0.1",  8002);
+#endif
+
+
+    delete sr;
+}
+
+void DapDataLocal::addServer(const DapServerInfo& dsi) {
+    for(auto& s: servers()) {
+        if(s == dsi) {
+            qWarning() << "[DataLocal::addServer] Server "
+                          "already exists in list";
+            return;
+        }
+    }
+    m_servers.push_back(dsi);
+}
+
+void DapDataLocal::setServerTheBest(const DapServerInfo &server){
+    int index = m_servers.indexOf(server);
+    if (index == -1) {
+        qWarning() << "Server not found";
+        return;
+    } else {
+        m_servers.move(index, 0);
+    }
+}
+
+/// Get login.
+/// @return Login.
+QString DapDataLocal::login() const
+{
+    return mLogin;
+}
+
+/// Set login.
+/// @param login Login.
+void DapDataLocal::setLogin(const QString &login)
+{
+    mLogin = login;
+    emit loginChanged(mLogin);
+}
+
+/// Get password.
+/// @return Password.
+QString DapDataLocal::password() const
+{
+    return mPassword;
+}
+
+/// Set password.
+/// @param password Password.
+void DapDataLocal::setPassword(const QString &password)
+{
+    mPassword = password;
+    emit passwordChanged(mPassword);
+}
+
+/// Get server name.
+/// @return Server name.
+QString DapDataLocal::serverName() const
+{
+    return mServerName;
+}
+
+/// Set server name.
+/// @param server Server name.
+void DapDataLocal::setServerName(const QString &serverName)
+{
+    if (serverName != mServerName) {
+        mServerName = serverName;
+        emit serverNameChanged(mServerName);
+    }
+}
+
+/// Get server name by its address.
+/// @param address Server address.
+/// @return Server name.
+QString DapDataLocal::getServerNameByAddress(const QString &address)
+{
+    QList<DapServerInfo>::const_iterator it = std::find_if(m_servers.cbegin(), m_servers.cend(), 
+        [=] (const DapServerInfo& server) 
+        { 
+            return server.address == address; 
+        });
+    
+    if(it != m_servers.cend())
+        return (*it).name;
+    
+    qCritical() << "Server with address " << address << " not found";
+    
+    return QString();
+}
+
+void /// Connect ComboBox to DataLocale. ComboBox currentText and DataLocale serverName will be synchronized
+/// @param a_comboBox ComboBox
+DapDataLocal::connectComboBox(QObject*a_comboBox)
+{
+    //connection when serverName in DataLocale changed
+    connect(this,       SIGNAL(serverNameChanged(QString)),
+            a_comboBox, SLOT  (setCurrentText(QString)));
+
+    //connection when comboBoxChanged
+    connect(a_comboBox, SIGNAL(currentTextChanged(QString)),
+            this,       SLOT  (setServerName(QString)));
+}
+
+void DapDataLocal::addServer(DapServerLocation location, const QString& name,
+                          const QString & address, quint16 port)
+{
+    DapServerInfo ss;
+    ss.name = name;
+    ss.location = location;
+    ss.address = address;
+    ss.port = port;
+    addServer(std::move(ss));
+}
+
+/**
+ * @brief DataLocal::locationToIcon
+ * @param a_location
+ * @return
+ */
+QString DapDataLocal::locationToIconPath(DapServerLocation loc)
+{
+    QString locPath = m_pictruePath.value(loc);
+    if (locPath == "") {
+        qWarning() << "Not found picture for current location. Return default!";
+        return m_pictruePath.value(DapServerLocation::UNKNOWN);
+    }
+    return locPath;
+}
diff --git a/DapDataLocal.h b/DapDataLocal.h
new file mode 100755
index 0000000..0dec283
--- /dev/null
+++ b/DapDataLocal.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#include <QList>
+#include <QString>
+#include <QObject>
+#include <QMap>
+#include <QPair>
+#include <QSettings>
+#include "DapServerInfo.h"
+
+#define SERVER_LIST_FILE "vpn-servers.xml"
+
+class DapDataLocal : public QObject
+{
+    Q_OBJECT
+    DapDataLocal();
+    const QString ServerListName;
+protected:
+    QString     mLogin;      ///< Login.
+    QString     mPassword;   ///< Password.
+    QString     mServerName; ///< Server name.
+
+    QString     m_cdbServersList;
+
+public:
+    using picturesMap = QMap<DapServerLocation, QString>;
+    static DapDataLocal * me(){ return _me?_me: _me = new DapDataLocal();}
+
+    void addServer(DapServerLocation location, const QString& name,
+                   const QString & address, quint16 port);
+    void addServer(const DapServerInfo& dsi);
+    QList<DapServerInfo>& servers(){return m_servers;}
+    const DapServerInfo& serverTheBest(){ return m_servers.at(0) ;  }
+    void setServerTheBest(const DapServerInfo& server);
+
+    QString locationToIconPath(DapServerLocation loc);
+    
+    QString login() const;
+    void setLogin(const QString &login);
+
+    QString password() const;
+    void setPassword(const QString &password);
+
+    QString serverName() const;
+    QString getServerNameByAddress(const QString& address);
+
+    const QString & cdbServersList() { return  m_cdbServersList; }
+
+    void connectComboBox(QObject *a_comboBox);
+
+public slots:
+    void setServerName(const QString &serverName);
+
+private:
+    static DapDataLocal *_me;
+    static QMap<DapServerLocation, QString> m_pictruePath;
+
+    QList<DapServerInfo> m_servers;
+
+    void parseXML(const QString& a_fname);
+    
+signals:
+    /// Signal emitted if login has changed.
+    /// @param login Login.
+    void loginChanged(const QString& login);
+    /// Signal emitted if password has changed.
+    /// @param password Password.
+    void passwordChanged(const QString& password);
+    /// Signal emitted if server name has changed.
+    /// @param serverName Server name.
+    void serverNameChanged(const QString& serverName);
+};
diff --git a/DapServersListRequester.h b/DapServersListRequester.h
index ceeeef1..cfdc973 100644
--- a/DapServersListRequester.h
+++ b/DapServersListRequester.h
@@ -31,7 +31,7 @@ signals:
  * @details Response example:
  * [
         {
-          "Name" : "ap-de-0-divevpn",
+          "Name" : "ap-de-0",
           "Port" : 8002,
           "Address" : "89.163.221.220",
           "Description" : "",
@@ -46,10 +46,10 @@ class DapServersListRequester
 private:
     explicit DapServersListRequester() {}
 public:
-    static DapServersListNetworkReply* sendRequest(const QString& host, quint16 port = 443) {
+    static DapServersListNetworkReply* sendRequest(const QString& host, quint16 port = 80) {
         auto networkReply = DapConnectClient::instance()->request_GET(host,
                                                                       port,
-                                                                      "/api/servers/list",
+                                                                      "/nodelist",
                                                                       true);
         DapReplyTimeout::set(networkReply, 10000); // 10 sec
         return new DapServersListNetworkReply(networkReply);
diff --git a/DapSession.cpp b/DapSession.cpp
index 229e9cb..23c15a6 100644
--- a/DapSession.cpp
+++ b/DapSession.cpp
@@ -32,12 +32,13 @@
 #include <QJsonDocument>
 #include <QJsonObject>
 
-const QString DapSession::URL_ENCRYPT("/1901248124123459");
-const QString DapSession::URL_STREAM("/874751843144");
-const QString DapSession::URL_DB("/01094787531354");
-const QString DapSession::URL_CTL("/091348758013553");
-const QString DapSession::URL_DB_FILE("/98971341937495431398");
-const QString DapSession::URL_SERVER_LIST("/slist");
+
+const QString DapSession::URL_ENCRYPT("/enc_init");
+const QString DapSession::URL_STREAM("/stream");
+const QString DapSession::URL_DB("/db");
+const QString DapSession::URL_CTL("/stream_ctl");
+const QString DapSession::URL_DB_FILE("/db_file");
+const QString DapSession::URL_SERVER_LIST("/nodelist");
 
 #define SESSION_KEY_ID_LEN 33
 
diff --git a/libdap-qt.pri b/libdap-qt.pri
index 95cfd94..fbc2049 100644
--- a/libdap-qt.pri
+++ b/libdap-qt.pri
@@ -1,7 +1,9 @@
+QT += core network xml
 INCLUDEPATH += ../libdap/include ../libdap/src
 INCLUDEPATH += ../libdap-crypto/include  ../libdap-crypto/src
 
 SOURCES += \
+    $$PWD/DapDataLocal.cpp \
     $$PWD/DapSession.cpp \
     $$PWD/DapCrypt.cpp \
     $$PWD/DapKeyMsrln.cpp \
@@ -14,6 +16,7 @@ SOURCES += \
     $$PWD/DapServersLocalStorage.cpp
 
 HEADERS += \
+    $$PWD/DapDataLocal.h \
     $$PWD/DapSession.h \
     $$PWD/DapCrypt.h \
     $$PWD/InterfaceDapKey.h \
-- 
GitLab