Teach frontend how to deal with official server replays (/watch)
authorWuzzy <Wuzzy2@mail.ru>
Fri, 10 May 2019 22:51:43 +0200
changeset 14903 5119203470f3
parent 14902 2dcc64515346
child 14904 6b69e97dce43
Teach frontend how to deal with official server replays (/watch)
ChangeLog.txt
QTfrontend/game.cpp
QTfrontend/game.h
QTfrontend/hwform.cpp
QTfrontend/hwform.h
QTfrontend/net/newnetclient.cpp
QTfrontend/net/newnetclient.h
--- a/ChangeLog.txt	Tue May 07 22:36:15 2019 +0200
+++ b/ChangeLog.txt	Fri May 10 22:51:43 2019 +0200
@@ -98,6 +98,7 @@
  + More intelligent automatic mission selection in campaign screen
  + New data directory for video thumbnails: Data/VideoThumbnails
  + Display a warning when the same key is used multiple times
+ * Fix broken handling of /watch chat command on official server
  * Fix renaming a video leading to loss of thumbnail after restart
  * Fix controls list failing to display correct key names with regards to keyboard layout
  * Fix force-locked schemes getting unlocked when changing map types
--- a/QTfrontend/game.cpp	Tue May 07 22:36:15 2019 +0200
+++ b/QTfrontend/game.cpp	Fri May 10 22:51:43 2019 +0200
@@ -497,6 +497,19 @@
     SetGameState(gsStarted);
 }
 
+void HWGame::PlayOfficialServerDemo()
+{
+    // TODO: Use gtDemo so fast-forward is available.
+    // Needs engine support first.
+    lastGameStartArgs.clear();
+    lastGameType = gtLocal;
+
+    gameType = gtLocal;
+    demo.clear();
+    Start(false);
+    SetGameState(gsStarted);
+}
+
 void HWGame::StartNet()
 {
     lastGameStartArgs.clear();
--- a/QTfrontend/game.h	Tue May 07 22:36:15 2019 +0200
+++ b/QTfrontend/game.h	Fri May 10 22:51:43 2019 +0200
@@ -76,6 +76,7 @@
         virtual ~HWGame();
         void AddTeam(const QString & team);
         void PlayDemo(const QString & demofilename, bool isSave);
+        void PlayOfficialServerDemo();
         void StartLocal();
         void StartQuick();
         void StartNet();
--- a/QTfrontend/hwform.cpp	Tue May 07 22:36:15 2019 +0200
+++ b/QTfrontend/hwform.cpp	Fri May 10 22:51:43 2019 +0200
@@ -1366,6 +1366,7 @@
     GoToPage(ID_PAGE_CONNECTING);
 
     connect(hwnet, SIGNAL(AskForRunGame()), this, SLOT(CreateNetGame()), Qt::QueuedConnection);
+    connect(hwnet, SIGNAL(AskForOfficialServerDemo()), this, SLOT(PlayOfficialServerDemo()), Qt::QueuedConnection);
     connect(hwnet, SIGNAL(redirected(quint16)), this, SLOT(NetRedirected(quint16)), Qt::QueuedConnection);
     connect(hwnet, SIGNAL(connected()), this, SLOT(NetConnected()), Qt::QueuedConnection);
     connect(hwnet, SIGNAL(Error(const QString&)), this, SLOT(NetError(const QString&)), Qt::QueuedConnection);
@@ -1926,6 +1927,23 @@
     game->StartNet();
 }
 
+void HWForm::PlayOfficialServerDemo()
+{
+    // go back in pages to prevent user from being stuck on certain pages
+    if(ui.Pages->currentIndex() == ID_PAGE_GAMESTATS ||
+       ui.Pages->currentIndex() == ID_PAGE_INGAME)
+        GoBack();
+
+    QString ammo;
+    ammo = ui.pageNetGame->pGameCFG->WeaponsName->itemData(
+               ui.pageNetGame->pGameCFG->WeaponsName->currentIndex()
+           ).toString();
+
+    CreateGame(ui.pageNetGame->pGameCFG, ui.pageNetGame->pNetTeamsWidget, ammo);
+
+    game->PlayOfficialServerDemo();
+}
+
 void HWForm::closeEvent(QCloseEvent *event)
 {
     config->SaveOptions();
--- a/QTfrontend/hwform.h	Tue May 07 22:36:15 2019 +0200
+++ b/QTfrontend/hwform.h	Fri May 10 22:51:43 2019 +0200
@@ -125,6 +125,7 @@
         void ShowFatalErrorMessage(const QString &);
         void GetRecord(RecordType type, const QByteArray & record);
         void CreateNetGame();
+        void PlayOfficialServerDemo();
         void UpdateWeapons();
         void DeleteWeapons(QString weaponsName);
         void AddWeapons(QString weaponsName, QString ammo);
--- a/QTfrontend/net/newnetclient.cpp	Tue May 07 22:36:15 2019 +0200
+++ b/QTfrontend/net/newnetclient.cpp	Fri May 10 22:51:43 2019 +0200
@@ -41,6 +41,7 @@
 {
     m_private_game = false;
     m_nick_registered = false;
+    m_demo_data_pending = false;
 
     m_roomsListModel = new RoomsListModel(this);
 
@@ -798,13 +799,35 @@
         return;
     }
 
-    if(netClientState == InRoom || netClientState == InGame)
+    if(netClientState == InLobby && lst[0] == "REPLAY_START")
+    {
+        if(lst.size() < 2 || lst[1] != mynick)
+        {
+            qWarning("Net: Bad REPLAY_START message");
+            return;
+        }
+
+        for(int i = 1; i < lst.size(); ++i)
+        {
+            if (lst[i] == mynick)
+            {
+                netClientState = InRoom;
+                m_demo_data_pending = true;
+                emit EnteredGame();
+                emit roomMaster(false);
+            }
+        }
+        return;
+    }
+
+    if(netClientState == InRoom || netClientState == InGame || netClientState == InDemo)
     {
         if (lst[0] == "EM")
         {
             if(lst.size() < 2)
             {
                 qWarning("Net: Bad EM message");
+                m_demo_data_pending = false;
                 return;
             }
             for(int i = 1; i < lst.size(); ++i)
@@ -812,9 +835,13 @@
                 QByteArray em = QByteArray::fromBase64(lst[i].toLatin1());
                 emit FromNet(em);
             }
+            m_demo_data_pending = false;
             return;
         }
+    }
 
+    if(netClientState == InRoom || netClientState == InGame)
+    {
         if (lst[0] == "ROUND_FINISHED")
         {
             emit FromNet(QByteArray("\x01o"));
@@ -856,8 +883,16 @@
 
         if (lst[0] == "RUN_GAME")
         {
-            netClientState = InGame;
-            emit AskForRunGame();
+            if(m_demo_data_pending)
+            {
+                netClientState = InDemo;
+                emit AskForOfficialServerDemo();
+            }
+            else
+            {
+                netClientState = InGame;
+                emit AskForRunGame();
+            }
             return;
         }
 
@@ -1065,6 +1100,13 @@
         netClientState = InRoom;
         RawSendNet(QString("ROUNDFINISHED%1%2").arg(delimiter).arg(correctly ? "1" : "0"));
     }
+    else if (netClientState == InDemo)
+    {
+        netClientState = InLobby;
+        askRoomsList();
+        emit LeftRoom(QString());
+        m_playersModel->resetRoomFlags();
+    }
 }
 
 void HWNewNet::banPlayer(const QString & nick)
--- a/QTfrontend/net/newnetclient.h	Tue May 07 22:36:15 2019 +0200
+++ b/QTfrontend/net/newnetclient.h	Fri May 10 22:51:43 2019 +0200
@@ -43,7 +43,7 @@
         Q_OBJECT
 
     public:
-        enum ClientState { Disconnected, Connecting, Redirected, Connected, InLobby, InRoom, InGame };
+        enum ClientState { Disconnected, Connecting, Redirected, Connected, InLobby, InRoom, InGame, InDemo };
 
         HWNewNet();
         ~HWNewNet();
@@ -73,6 +73,7 @@
         QString seed;
         bool m_game_connected;
         bool m_nick_registered;
+        bool m_demo_data_pending;
         RoomsListModel * m_roomsListModel;
         PlayersListModel * m_playersModel;
         QSortFilterProxyModel * m_lobbyPlayersModel;
@@ -97,6 +98,7 @@
 
     signals:
         void AskForRunGame();
+        void AskForOfficialServerDemo();
         void connected();
         void disconnected(const QString & reason);
         void redirected(quint16 port);