#pragma once #include #include #include "Keys.h" #include #include #include class PSClient { private: int id; Network::Klient *klient; char *schlüssel; unsigned char schlüsselLän; int port; char *ip; int ref; public: // Konstruktor PSClient( int klientId, unsigned short port, char *ip, char *key, unsigned char keyLen ) { klient = 0; id = klientId; this->port = port; this->ip = new char[ textLength( ip ) + 1 ]; memcpy( this->ip, ip, textLength( ip ) + 1 ); schlüsselLän = keyLen; schlüssel = new char[ keyLen ]; memcpy( schlüssel, key, keyLen ); ref = 1; } // Destruktor ~PSClient() { delete[] schlüssel; if( klient ) trenne( 1 ); delete[] ip; if( klient ) klient->release(); } // nicht constant bool verbinde() { if( klient ) return 1; klient = new Network::Klient(); int l = 0; char *key; Keys::getServerKey( &key, l, Keys::PATCH, Keys::SENDEN ); klient->setSendeKey( key, l ); delete[] key; Keys::getServerKey( &key, l, Keys::PATCH, Keys::EMPFANGEN ); klient->setEmpfangKey( key, l ); delete[] key; if( klient->verbinde( port, ip ) ) { klient->sende( "\0", 1 ); // Verschlüsselung Aktivieren if( klient->sendeEncrypted( "\1", 1 ) ) { klient->sendeEncrypted( (char*)&id, 4 ); klient->sendeEncrypted( "\2", 1 ); // 64 Bit Client char serverReturn = 0; klient->getNachrichtEncrypted( &serverReturn, 1 ); if( serverReturn == 3 ) { char byte = 0; klient->getNachrichtEncrypted( &byte, 1 ); char *f = new char[ byte + 1 ]; f[ byte ] = 0; klient->getNachrichtEncrypted( f, byte ); std::cerr << "error while identifyin client Patch Server returned: " << f << "\n"; delete[]f; klient->sendeEncrypted( "\3", 1 ); klient->getNachrichtEncrypted( &serverReturn, 1 ); klient->trenne(); return 0; } klient->setSendeKey( (char*)schlüssel, schlüsselLän ); klient->setEmpfangKey( (char*)schlüssel, schlüsselLän ); } else { std::cerr << "network error while sending to Patch Server\n"; klient = klient->release(); return 0; } } else { std::cerr << "network error while connecting to Patch Server\n"; klient = klient->release(); return 0; } return 1; } KSGTDatei *getDateiGruppenListe() { verbinde(); if( !klient ) return 0; klient->sendeEncrypted( "\xC", 1 ); char ret = 0; klient->getNachrichtEncrypted( &ret, 1 ); if( ret == 3 ) { // error klient->getNachrichtEncrypted( &ret, 1 ); char *msg = new char[ ret + 1 ]; msg[ ret ] = 0; if( ret ) klient->getNachrichtEncrypted( msg, ret ); std::cerr << "error while getDateiGruppenListe Patch Server returned: " << msg << "\n"; delete[] msg; return 0; } KSGTDatei *dgtb = new KSGTDatei(); int id = 0; klient->getNachrichtEncrypted( (char*)&id, 4 ); while( id ) { RCArray< Text > *zeile = new RCArray< Text >(); Text *idT = new Text(); idT->append( id ); zeile->set( idT, 0 ); int län = 0; klient->getNachrichtEncrypted( (char*)&län, 4 ); char *pfad = new char[ län + 1 ]; pfad[ län ] = 0; if( län ) klient->getNachrichtEncrypted( pfad, län ); zeile->set( new Text( pfad ), 1 ); delete[] pfad; int vs = 0; klient->getNachrichtEncrypted( (char*)&vs, 4 ); Text *vsT = new Text(); vsT->append( vs ); zeile->set( vsT, 2 ); dgtb->addZeile( 3, zeile ); zeile->release(); klient->getNachrichtEncrypted( (char*)&id, 4 ); } klient->sendeEncrypted( "\1", 1 ); return dgtb; } KSGTDatei *getDateiListe( int gruppe ) { verbinde(); if( !klient ) return 0; klient->sendeEncrypted( "\x9", 1 ); char ret = 0; klient->getNachrichtEncrypted( &ret, 1 ); if( ret == 1 ) { klient->sendeEncrypted( (char*)&gruppe, 4 ); klient->getNachrichtEncrypted( &ret, 1 ); } if( ret == 3 ) { // error klient->getNachrichtEncrypted( &ret, 1 ); char *msg = new char[ ret + 1 ]; msg[ ret ] = 0; if( ret ) klient->getNachrichtEncrypted( msg, ret ); std::cerr << "error while getDateiListe Patch Server returned: " << msg << "\n"; delete[] msg; return 0; } KSGTDatei *dtb = new KSGTDatei(); int län = 0; klient->getNachrichtEncrypted( (char*)&län, 4 ); while( län ) { RCArray< Text > *zeile = new RCArray< Text >(); zeile->set( new Text( "1" ), 0 ); char *pfad = new char[ län + 1 ]; pfad[ län ] = 0; klient->getNachrichtEncrypted( pfad, län ); zeile->set( new Text( pfad ), 1 ); delete[] pfad; int vs = 0; klient->getNachrichtEncrypted( (char*)&vs, 4 ); Text *vsT = new Text(); vsT->append( vs ); zeile->set( vsT, 2 ); dtb->addZeile( 3, zeile ); zeile->release(); klient->getNachrichtEncrypted( (char*)&län, 4 ); } klient->getNachrichtEncrypted( (char*)&län, 4 ); while( län ) { RCArray< Text > *zeile = new RCArray< Text >(); zeile->set( new Text( "0" ), 0 ); char *pfad = new char[ län + 1 ]; pfad[ län ] = 0; klient->getNachrichtEncrypted( pfad, län ); zeile->set( new Text( pfad ), 1 ); delete[] pfad; dtb->addZeile( 2, zeile ); zeile->release(); klient->getNachrichtEncrypted( (char*)&län, 4 ); } return dtb; } __int64 getDateiGröße( int gruppe, const char *pfad ) { verbinde(); if( !klient ) return 0; klient->sendeEncrypted( "\xA", 1 ); char ret = 0; klient->getNachrichtEncrypted( &ret, 1 ); if( ret == 1 ) { klient->sendeEncrypted( (char*)&gruppe, 4 ); klient->getNachrichtEncrypted( &ret, 1 ); } if( ret == 3 ) { // error klient->getNachrichtEncrypted( &ret, 1 ); char *msg = new char[ ret + 1 ]; msg[ ret ] = 0; if( ret ) klient->getNachrichtEncrypted( msg, ret ); std::cerr << "error while getDateiGröße Patch Server returned: " << msg << "\n"; delete[] msg; return 0; } if( ret == 2 ) { // verweis auf anderen Server klient->getNachrichtEncrypted( (char*)&port, 4 ); int län = 0; klient->getNachrichtEncrypted( (char*)&län, 4 ); delete[] ip; ip = new char[ län + 1 ]; ip[ län ] = 0; klient->getNachrichtEncrypted( ip, län ); if( !trenne( 0 ) ) { delete[] ip; return 0; } if( !verbinde() ) { delete[] ip; return 0; } delete[] ip; return getDateiGröße( gruppe, pfad ); } int län = textLength( pfad ); klient->sendeEncrypted( (char*)&län, 4 ); klient->sendeEncrypted( pfad, län ); __int64 größe = 0; klient->getNachrichtEncrypted( (char*)&größe, 8 ); return größe; } bool downloadDatei( int gruppe, __int64 *start, const char *pfad, const char *zielPfad ) { verbinde(); if( !klient ) return 0; Datei *zielD = new Datei(); zielD->setDatei( zielPfad ); if( !zielD->existiert() ) zielD->erstellen(); bool ok = 0; if( !( *start ) ) // datei neu erstellen ok = zielD->open( Datei::Style::schreiben ); else // datei weiterschreiben ok = zielD->open( Datei::Style::schreiben | Datei::Style::lesen ); if( !ok ) { zielD->release(); return 0; } zielD->setSPosition( *start, 0 ); klient->sendeEncrypted( "\xB", 1 ); char ret = 0; klient->getNachrichtEncrypted( &ret, 1 ); if( ret == 1 ) { klient->sendeEncrypted( (char*)&gruppe, 4 ); klient->getNachrichtEncrypted( &ret, 1 ); } if( ret == 3 ) { // error klient->getNachrichtEncrypted( &ret, 1 ); char *msg = new char[ ret + 1 ]; msg[ ret ] = 0; if( ret ) klient->getNachrichtEncrypted( msg, ret ); std::cerr << "error while downloadDatei Patch Server returned: " << msg << "\n"; delete[] msg; zielD->close(); zielD->release(); return 0; } if( ret == 2 ) { // verweis auf anderen Server klient->getNachrichtEncrypted( (char*)&port, 4 ); int län = 0; klient->getNachrichtEncrypted( (char*)&län, 4 ); delete[] ip; ip = new char[ län + 1 ]; ip[ län ] = 0; klient->getNachrichtEncrypted( ip, län ); if( !trenne( 0 ) ) { delete[] ip; zielD->close(); zielD->release(); return 0; } if( !verbinde() ) { delete[] ip; zielD->close(); zielD->release(); return 0; } delete[] ip; zielD->close(); zielD->release(); return downloadDatei( gruppe, start, pfad, zielPfad ); } int län = textLength( pfad ); klient->sendeEncrypted( (char*)&län, 4 ); klient->sendeEncrypted( pfad, län ); klient->sendeEncrypted( (char*)start, 8 ); char *bytes = new char[ 2048 ]; unsigned short byteLän = 0; klient->getNachricht( (char*)&byteLän, 2 ); if( byteLän ) { int bps = 0; double sec = 0; while( 1 ) { klient->getNachricht( bytes, byteLän ); zielD->schreibe( bytes, byteLän ); ( *start ) += byteLän; bps += byteLän; if( byteLän == 2048 ) { klient->getNachricht( (char*)&byteLän, 2 ); // sendelänge empfangen if( !byteLän ) break; } else break; } } delete[] bytes; klient->sendeEncrypted( "\1", 1 ); zielD->close(); zielD->release(); return 1; } bool trenne( bool abmelden ) { verbinde(); if( !klient ) return 1; if( abmelden ) { klient->sendeEncrypted( "\4", 1 ); char ret = 0; klient->getNachrichtEncrypted( &ret, 1 ); if( ret == 3 ) { // error klient->getNachrichtEncrypted( &ret, 1 ); char *msg = new char[ ret + 1 ]; msg[ ret ] = 0; if( ret ) klient->getNachrichtEncrypted( msg, ret ); std::cerr << "error while unregister Client Patch Server returned: " << msg << "\n"; delete[] msg; } } klient->sendeEncrypted( "\3", 1 ); char ret = 0; klient->getNachrichtEncrypted( &ret, 1 ); if( ret == 3 ) { // error klient->getNachrichtEncrypted( &ret, 1 ); char *msg = new char[ ret + 1 ]; msg[ ret ] = 0; if( ret ) klient->getNachrichtEncrypted( msg, ret ); std::cerr << "error while trenne Patch Server returned: " << msg << "\n"; delete[] msg; } klient->trenne(); klient = klient->release(); return 1; } // Reference Counting PSClient *getThis() { ref++; return this; } PSClient *release() { ref--; if( !ref ) delete this; return 0; } };