Переглянути джерело

HistorieClient hinzugefügt

Kolja Strohm 6 роки тому
батько
коміт
6a438e975f

+ 5 - 2
Include/KSGNetwork.h

@@ -143,6 +143,8 @@ namespace KSGClient
         virtual AccountActivityInfo *release() = 0;
     };
 
+    class SpielServerClient;
+
     // Enthält eine Nachricht, die von Chat Server gesendet wurde
     struct ChatServerNachricht
     {
@@ -152,6 +154,7 @@ namespace KSGClient
         int gruppe; // Beteiligte Gruppe
         int chatroom; // Beteiligter Chatraum
         Framework::Array< int > ids; // Liste mit Account Ids
+        SpielServerClient *client; // ein Client zum zugewiesenen Spiel Server
     };
 
     // Enthält eine Nachricht von dem Spiel Server
@@ -1010,11 +1013,11 @@ namespace KSGClient
     protected:
         // verbindet sich mit dem zugewiesenen Historie Server
         //  Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
-        virtual bool verbinde( char *ip, int port ) = 0;
+        virtual bool verbinde() = 0;
         // Trennt die Verbindung zum Server
         //  Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
         //  Sollte erst nach einem erfolgreichen Aufruf von verbinde aufgerufen werden
-        virtual bool trenne() = 0;
+        virtual bool trenne( bool abmelden ) = 0;
 
     public:
         // Lädt die Spiel Aufzeichnung eines Spiels herunter und speichert sie unter data/tmp/historie/{spielId}

+ 2 - 2
KSGNetwork/ChatClient.cpp

@@ -2,6 +2,7 @@
 #include "Keys.h"
 #include <Klient.h>
 #include <Globals.h>
+#include "SpielClient.h"
 
 using namespace KSGClient;
 
@@ -853,7 +854,6 @@ bool ChatClient::getNextMessage( ChatServerNachricht &nachricht )
                 unsigned char *ip = new unsigned char[ 4 ];
                 empfangen->getNachrichtEncrypted( (char*)&port, 2 );
                 empfangen->getNachrichtEncrypted( (char*)ip, 4 );
-                nachricht.account = port;
                 Text *ipT = new Text( "" );
                 ipT->append( (int)ip[ 0 ] );
                 ipT->append( "." );
@@ -862,8 +862,8 @@ bool ChatClient::getNextMessage( ChatServerNachricht &nachricht )
                 ipT->append( (int)ip[ 2 ] );
                 ipT->append( "." );
                 ipT->append( (int)ip[ 3 ] );
-                nachricht.message = ipT->getText();
                 delete[] ip;
+                nachricht.client = new SpielClient( cId, port, ipT->getText(), this->key, this->keyLen );
                 ipT->release();
             }
             break;

+ 224 - 0
KSGNetwork/HistorieClient.cpp

@@ -0,0 +1,224 @@
+#include "HistorieClient.h"
+#include "Keys.h"
+#include <Datei.h>
+
+using namespace KSGClient;
+
+// Inhalt der HistorieClient Klasse
+
+// Konstruktor
+HistorieClient::HistorieClient( int klientId, unsigned short port, char *ip, char *key, unsigned char keyLen, int spielId )
+{
+    ref = 1;
+    this->ip = ip;
+    this->port = port;
+    cId = klientId;
+    k = 0;
+    this->key = new char[ keyLen ];
+    memcpy( this->key, key, keyLen );
+    this->keyLen = keyLen;
+    this->spielId = spielId;
+}
+
+// Destruktor
+HistorieClient::~HistorieClient()
+{
+    trenne( 1 );
+    delete[] key;
+}
+
+// verbindet sich mit dem zugewiesenen Historie Server
+//  Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
+bool HistorieClient::verbinde()
+{
+    cs.lock();
+    if( k )
+    {
+        cs.unlock();
+        return 1;
+    }
+    k = new Network::Klient();
+    int l = 0;
+    char *key;
+    Keys::getServerKey( &key, l, Keys::HISTORIE, Keys::SENDEN );
+    k->setSendeKey( key, l );
+    delete[] key;
+    Keys::getServerKey( &key, l, Keys::HISTORIE, Keys::EMPFANGEN );
+    k->setEmpfangKey( key, l );
+    delete[] key;
+    if( k->verbinde( port, ip ) )
+    {
+        if( k->sendeEncrypted( "\1", 1 ) )
+        {
+            k->sendeEncrypted( (char*)&cId, 4 );
+            char serverReturn = 0;
+            k->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char byte = 0;
+                k->getNachrichtEncrypted( &byte, 1 );
+                char *f = new char[ byte + 1 ];
+                f[ byte ] = 0;
+                k->getNachrichtEncrypted( f, byte );
+                err = "error while identifying client Historie Server returned: ";
+                err += f;
+                delete[]f;
+                trenne( 0 );
+                cs.unlock();
+                return 0;
+            }
+            k->setSendeKey( this->key, this->keyLen );
+            k->setEmpfangKey( this->key, this->keyLen );
+        }
+        else
+        {
+            err = "network error while sending to Historie Server";
+            k = k->release();
+            cs.unlock();
+            return 0;
+        }
+    }
+    else
+    {
+        err = "network error while connecting to Historie Server";
+        k = k->release();
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+// Trennt die Verbindung zum Server
+//  Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
+//  Sollte erst nach einem erfolgreichen Aufruf von verbinde aufgerufen werden
+bool HistorieClient::trenne( bool abmelden )
+{
+    if( !k && !abmelden )
+        return 1;
+    if( !k && abmelden )
+        verbinde();
+    if( !k )
+        return 0;
+    char serverReturn;
+    if( abmelden )
+    {
+        k->sendeEncrypted( "\4", 1 );
+        k->getNachrichtEncrypted( &serverReturn, 1 );
+        if( serverReturn == 3 )
+        {
+            char län = 0;
+            k->getNachrichtEncrypted( &län, 1 );
+            char *nachricht = new char[ län + 1 ];
+            nachricht[ län ] = 0;
+            k->getNachrichtEncrypted( nachricht, län );
+            err = nachricht;
+            delete[]nachricht;
+        }
+    }
+    k->sendeEncrypted( "\3", 1 );
+    k->getNachrichtEncrypted( &serverReturn, 1 );
+    k->trenne();
+    k = k->release();
+    return 1;
+}
+
+// Lädt die Spiel Aufzeichnung eines Spiels herunter und speichert sie unter data/tmp/historie/{spielId}
+//  Die Spielid wurde dem Objekt zum Zeitpunkt der Erstellung vom Information Server mitgegeben
+//  Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
+//  Diese Funktion verbindet sich selbstständig mit dem Server und trennt die Verbindung nach Beendigung des Vorgangs
+bool HistorieClient::downloadSpielHistorie()
+{
+    if( DateiIstVerzeichnis( Text( "data/tmp/historie/" ) += spielId ) )
+        return 1;
+    cs.lock();
+    if( !verbinde() )
+    {
+        cs.unlock();
+        return 0;
+    }
+    k->sendeEncrypted( "\6", 1 );
+    char ret = 0;
+    k->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        k->sendeEncrypted( (char*)&spielId, 4 );
+        k->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            char län = 0;
+            k->getNachrichtEncrypted( &län, 1 );
+            while( län )
+            {
+                char *pf = new char[ län + 1 ];
+                pf[ län ] = 0;
+                k->getNachrichtEncrypted( pf, län );
+                __int64 gr = 0;
+                k->getNachrichtEncrypted( (char*)&gr, 8 );
+                Text *pfad = new Text( "data/tmp/historie/" );
+                pfad->append( spielId );
+                pfad->append( pf );
+                delete[] pf;
+                Datei *d = new Datei();
+                d->setDatei( pfad );
+                d->erstellen();
+                d->open( Datei::Style::schreiben );
+                char *bytes = new char[ 2048 ];
+                while( gr )
+                {
+                    int dLän = gr > 2048 ? 2048 : (int)gr;
+                    k->getNachricht( bytes, dLän );
+                    d->schreibe( bytes, dLän );
+                    gr -= dLän;
+                }
+                delete[] bytes;
+                d->close();
+                d->release();
+                k->getNachrichtEncrypted( &län, 1 );
+            }
+            trenne( 0);
+            cs.unlock();
+            return 1;
+        }
+    }
+    if( ret == 3 )
+    {
+        char län = 0;
+        k->getNachrichtEncrypted( &län, 1 );
+        char *nachricht = new char[ län + 1 ];
+        nachricht[ län ] = 0;
+        k->getNachrichtEncrypted( nachricht, län );
+        err = nachricht;
+        delete[]nachricht;
+        trenne( 0 );
+        cs.unlock();
+        return 0;
+    }
+    err = "unbekannter Fehler";
+    trenne( 0 );
+    cs.unlock();
+    return 0;
+}
+
+// gibt den Letzten Fehlertext zuück
+//  sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist
+char *HistorieClient::getLetzterFehler() const
+{
+    return err;
+}
+
+// Erhöht den Reference Counter um 1 un gibt this zurück
+HistorieServerClient *HistorieClient::getThis()
+{
+    ref++;
+    return this;
+}
+
+// Verringert den Reference Counter um 1 und gibt 0 zurück.
+//  Falls der Reference Counter nach dem Aufruf auf 0 ist löscht sich das Objekt selbst 
+HistorieServerClient *HistorieClient::release()
+{
+    if( !--ref )
+        delete this;
+    return 0;
+}

+ 52 - 0
KSGNetwork/HistorieClient.h

@@ -0,0 +1,52 @@
+#pragma once
+
+#include "../Include/KSGNetwork.h"
+#include <Critical.h>
+
+namespace KSGClient
+{
+    // Wird verwendet um Statistiken und Aufzeichnungen von vergangenen Spielen abzufragen
+    //  Kann nur von eingeloggten Clients verwendet werden
+    class HistorieClient : public HistorieServerClient
+    {
+    private:
+        int ref;
+        Framework::Text ip;
+        unsigned short port;
+        int cId;
+        Network::Klient *k;
+        char *key;
+        unsigned char keyLen;
+        Framework::Critical cs;
+        Framework::Text err;
+        int spielId;
+
+    protected:
+        // verbindet sich mit dem zugewiesenen Historie Server
+        //  Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
+        bool verbinde() override;
+        // Trennt die Verbindung zum Server
+        //  Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
+        //  Sollte erst nach einem erfolgreichen Aufruf von verbinde aufgerufen werden
+        bool trenne( bool abmelden ) override;
+
+    public:
+        // Konstruktor
+        HistorieClient( int klientId, unsigned short port, char *ip, char *key, unsigned char keyLen, int spielId );
+        // Destruktor
+        ~HistorieClient();
+        // Lädt die Spiel Aufzeichnung eines Spiels herunter und speichert sie unter data/tmp/historie/{spielId}
+        //  Die Spielid wurde dem Objekt zum Zeitpunkt der Erstellung vom Information Server mitgegeben
+        //  Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
+        //  Diese Funktion verbindet sich selbstständig mit dem Server und trennt die Verbindung nach Beendigung des Vorgangs
+        bool downloadSpielHistorie() override;
+        // gibt den Letzten Fehlertext zuück
+        //  sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist
+        char *getLetzterFehler() const override;
+        // Erhöht den Reference Counter um 1 un gibt this zurück
+        HistorieServerClient *getThis() override;
+        // Verringert den Reference Counter um 1 und gibt 0 zurück.
+        //  Falls der Reference Counter nach dem Aufruf auf 0 ist löscht sich das Objekt selbst 
+        HistorieServerClient *release() override;
+    };
+}

+ 2 - 0
KSGNetwork/KSGNetwork.vcxproj

@@ -151,6 +151,7 @@
     <ClInclude Include="AnmeldungClient.h" />
     <ClInclude Include="ChatClient.h" />
     <ClInclude Include="ErhaltungClient.h" />
+    <ClInclude Include="HistorieClient.h" />
     <ClInclude Include="InformationClient.h" />
     <ClInclude Include="KartenClient.h" />
     <ClInclude Include="Keys.h" />
@@ -167,6 +168,7 @@
     <ClCompile Include="AnmeldungClient.cpp" />
     <ClCompile Include="ChatClient.cpp" />
     <ClCompile Include="ErhaltungClient.cpp" />
+    <ClCompile Include="HistorieClient.cpp" />
     <ClCompile Include="InformationClient.cpp" />
     <ClCompile Include="KartenClient.cpp" />
     <ClCompile Include="Keys.cpp" />

+ 6 - 0
KSGNetwork/KSGNetwork.vcxproj.filters

@@ -60,6 +60,9 @@
     <ClInclude Include="SpielClient.h">
       <Filter>Headerdateien</Filter>
     </ClInclude>
+    <ClInclude Include="HistorieClient.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="MainClient.cpp">
@@ -101,5 +104,8 @@
     <ClCompile Include="SpielClient.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
+    <ClCompile Include="HistorieClient.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>