#include "News.h" #include #include #include #include #include #include #include #include "Keys.h" void KSGSRückruf( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **ret ) { if( !p ) return; ( (News*)p )->rückruf( parameter, ret ); } // Inhalt der News Klasse aus News.h // Konstruktor News::News( Bildschirm *zB, Schrift *zS ) { ref = 1; // Ladeanimation laden Animation2DData *aData = new Animation2DData(); LTDBDatei *aDatei = new LTDBDatei(); aDatei->setDatei( new Text( "data/bilder/ladeanimation.ltdb" ) ); aDatei->leseDaten( 0 ); aData->ladeAnimation( aDatei ); aData->setFPS( 30 ); aData->setWiederhohlend( 1 ); aData->setTransparent( 0 ); laden = new Animation2D(); laden->setPosition( zB->getBackBufferSize() / 2 - Punkt( 25, 25 ) ); laden->setSize( 50, 50 ); laden->setAPS( 450 ); laden->setAnimationDataZ( aData ); laden->setRahmen( 1 ); laden->setRahmenBreite( 1 ); laden->setRahmenFarbe( 0xFFFFFFFF ); laden->setSichtbar( 0 ); zB->setOnTopZeichnung( laden ); // Fehler Textfeld Initialisieren fehler = new TextFeld(); fehler->setStyle( TextFeld::Style::Text & ~TextFeld::Style::Sichtbar ); fehler->setPosition( 10, 60 ); fehler->setSize( 480, 312 ); fehler->setSchriftFarbe( 0xFFFFFFFF ); fehler->setSchriftZ( zS->getThis() ); fehler->setText( "Fehler beim Laden der Seite!\n" ); zB->addMember( fehler ); // Startwerte Initialisieren screen = zB->getThis(); schrift = zS->getThis(); // DLL Datei Laden ksgsDll = LoadLibrary( "data/bin/KSGScript.dll" ); if( !ksgsDll ) { // Error fehler->addZeile( "Die DLL Datei 'data/bin/KSGScript.dll' wurde nicht gefunden." ); fehler->addStyle( TextFeld::Style::Sichtbar ); laden->setSichtbar( 0 ); screen->setOnTop( 0 ); run = 0; return; } KSGSGetZeichnung getKSGSZeichnung = (KSGSGetZeichnung)GetProcAddress( ksgsDll, KSGS_START_FUNKTION ); if( !getKSGSZeichnung ) { // Error fehler->addZeile( "Die Funktion '" KSGS_START_FUNKTION "' wurde in der\nDLL Datei 'data/bil/KSGScript.dll' nicht gefunden." ); fehler->addStyle( TextFeld::Style::Sichtbar ); laden->setSichtbar( 0 ); screen->setOnTop( 0 ); run = 0; return; } frame = getKSGSZeichnung(); if( !frame ) { // Error fehler->addZeile( "Unbekannter Fehler." ); fehler->addStyle( TextFeld::Style::Sichtbar ); laden->setSichtbar( 0 ); screen->setOnTop( 0 ); run = 0; return; } frame->setSchriftZ( schrift->getThis() ); frame->setBildschirmZ( screen->getThis() ); frame->setPosition( 10, 60 ); frame->setSize( 480, 312 ); frame->setRückrufParam( this ); frame->setRückrufFunktion( KSGSRückruf ); screen->addMember( frame ); scriptName = new Text( "Patcher/Start" ); // Lade Thread starten start(); } // Destruktor News::~News() { warteAufThread( INFINITE ); if( frame ) { frame->zurücksetzen(); frame->release(); } if( ksgsDll ) FreeLibrary( ksgsDll ); if( scriptName ) scriptName->release(); laden->release(); screen->release(); fehler->release(); schrift->release(); } // nicht constant void News::rückruf( RCArray< KSGSVariable > *parameter, KSGSVariable **ret ) { if( isRunning() ) return; KSGSVariable *bef = parameter->z( 0 ); if( !bef ) return; Text *sn = bef->getText(); if( !sn || !sn->getLength() ) { if( sn ) sn->release(); return; } scriptName->setText( sn->getText() ); sn->release(); start(); } void News::thread() { screen->setOnTop( 1 ); laden->setSichtbar( 1 ); frame->zurücksetzen(); // KSGScript Seite Herunterladen NewsKlient *klient = new NewsKlient(); if( !klient->verbinde() ) { klient->release(); fehler->addZeile( "Fehler beim verbinden mit dem News-Server." ); fehler->addStyle( TextFeld::Style::Sichtbar ); laden->setSichtbar( 0 ); screen->setOnTop( 0 ); run = 0; return; } if( !klient->downloadSeite( scriptName->getText() ) ) { klient->trenne( 1 ); klient->release(); fehler->addZeile( "Die Seite konnte nicht herruntergeladen werden." ); fehler->addStyle( TextFeld::Style::Sichtbar ); laden->setSichtbar( 0 ); screen->setOnTop( 0 ); run = 0; return; } klient->trenne( 1 ); klient->release(); // KSGScript Laden Text *pfad = new Text( "data/tmp/news/" ); pfad->append( scriptName->getText() ); pfad->append( "/seite.ksgs" ); frame->setScriptDatei( pfad ); if( !frame->neuLaden() ) { // error fehler->addZeile( "Es befindet sich ein Scriptfehler auf dieser Seite." ); fehler->addStyle( TextFeld::Style::Sichtbar ); laden->setSichtbar( 0 ); screen->setOnTop( 0 ); run = 0; return; } laden->setSichtbar( 0 ); screen->setOnTop( 0 ); run = 0; } // Reference Counting News *News::getThis() { ref++; return this; } News *News::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der NewsKlient Klasse aus News.h // Konstruktor NewsKlient::NewsKlient() { // lade Client id id = 0; Datei *dat = new Datei(); dat->setDatei( new Text( "data/tmp/k.id" ) ); dat->open( Datei::Style::lesen ); dat->lese( (char*)&id, 4 ); dat->close(); // lade Schlüssel dat->setDatei( new Text( "data/tmp/schlüssel.netw" ) ); dat->open( Datei::Style::lesen ); schlüsselLän = 0; dat->lese( &schlüsselLän, 1 ); schlüssel = new char[ schlüsselLän ]; dat->lese( schlüssel, schlüsselLän ); dat->close(); dat->release(); // Initialisierung verbunden = 0; klient = 0; InitializeCriticalSection( &cs ); ref = 1; } // Destruktor NewsKlient::~NewsKlient() { if( verbunden ) trenne( 1 ); delete[] schlüssel; if( klient ) klient->release(); DeleteCriticalSection( &cs ); } // nicht constant void NewsKlient::lock() { EnterCriticalSection( &cs ); } void NewsKlient::unlock() { LeaveCriticalSection( &cs ); } bool NewsKlient::verbinde() { lock(); if( verbunden ) { unlock(); return 1; } if( !klient ) { InitDatei *dat = new InitDatei( "data/optionen.ini" ); dat->laden(); Text *ipT = dat->getWert( "ServerIP" ); unsigned short msPort = (unsigned short)TextZuInt( dat->zWert( "ServerPort" )->getText(), 10 ); dat->release(); int län = ipT->getLength(); char *msIp = new char[ län + 1 ]; msIp[ län ] = 0; for( int i = 0; i < län; i++ ) msIp[ i ] = ipT->getText()[ i ]; ipT->release(); klient = new Klient(); int l; char *key; Keys::getServerKey( &key, l, Keys::MAIN, Keys::SENDEN ); klient->setSendeKey( key, l ); delete[] key; Keys::getServerKey( &key, l, Keys::MAIN, Keys::SENDEN ); klient->setEmpfangKey( key, l ); delete[] key; if( !klient->verbinde( msPort, msIp ) ) { klient = klient->release(); delete[]msIp; unlock(); return 0; } delete[]msIp; klient->sende( "\0", 1 ); // verschlüsselung aktivieren klient->sendeEncrypted( "\1", 1 ); klient->sendeEncrypted( (char*)&id, 4 ); char serverReturn = 0; klient->getNachrichtEncrypted( &serverReturn, 1 ); if( serverReturn == 3 ) { char byte = 0; klient->getNachrichtEncrypted( &byte, 1 ); char *fehler = new char[ byte + 1 ]; fehler[ byte ] = 0; klient->getNachrichtEncrypted( fehler, byte ); delete[] fehler; klient->sendeEncrypted( "\3", 1 ); klient->getNachrichtEncrypted( &serverReturn, 1 ); klient->trenne(); klient = klient->release(); unlock(); return 0; } klient->setSendeKey( this->schlüssel, schlüsselLän ); klient->setEmpfangKey( this->schlüssel, schlüsselLän ); klient->sendeEncrypted( "\6\x9", 2 ); char byte = 0; klient->getNachrichtEncrypted( &byte, 1 ); if( byte == 2 ) { unsigned char nsIp[ 4 ]; klient->getNachrichtEncrypted( (char *)nsIp, 4 ); unsigned short nsPort = 0; klient->getNachrichtEncrypted( (char*)&nsPort, 2 ); klient->sendeEncrypted( "\3", 1 ); klient->getNachrichtEncrypted( &serverReturn, 1 ); klient->trenne(); Text *nsIpT = new Text( "" ); nsIpT->append( (int)nsIp[ 0 ] ); nsIpT->append( "." ); nsIpT->append( (int)nsIp[ 1 ] ); nsIpT->append( "." ); nsIpT->append( (int)nsIp[ 2 ] ); nsIpT->append( "." ); nsIpT->append( (int)nsIp[ 3 ] ); int l; char *key; Keys::getServerKey( &key, l, Keys::NEWS, Keys::SENDEN ); klient->setSendeKey( key, l ); delete[] key; Keys::getServerKey( &key, l, Keys::NEWS, Keys::SENDEN ); klient->setEmpfangKey( key, l ); delete[] key; klient->verbinde( nsPort, nsIpT->getText() ); nsIpT = nsIpT->release(); klient->sendeEncrypted( "\3", 1 ); klient->getNachrichtEncrypted( &serverReturn, 1 ); klient->trenne(); } if( byte == 3 ) { klient->getNachrichtEncrypted( &byte, 1 ); char *fehler = new char[ byte + 1 ]; fehler[ byte ] = 0; klient->getNachrichtEncrypted( fehler, byte ); delete[]fehler; klient->sendeEncrypted( "\3", 1 ); klient->getNachrichtEncrypted( &serverReturn, 1 ); klient->trenne(); klient = klient->release(); unlock(); return 0; } } int l; char *key; Keys::getServerKey( &key, l, Keys::NEWS, Keys::SENDEN ); klient->setSendeKey( key, l ); delete[] key; Keys::getServerKey( &key, l, Keys::NEWS, Keys::SENDEN ); klient->setEmpfangKey( key, l ); delete[] key; if( klient->verbinde( klient->getServerPort(), klient->getServerIp() ) ) { if( klient->sendeEncrypted( "\1", 1 ) ) { klient->sendeEncrypted( (char*)&id, 4 ); char serverReturn = 0; klient->getNachrichtEncrypted( &serverReturn, 1 ); if( serverReturn == 3 ) { char byte = 0; klient->getNachrichtEncrypted( &byte, 1 ); char *fehler = new char[ byte + 1 ]; fehler[ byte ] = 0; klient->getNachrichtEncrypted( fehler, byte ); delete[]fehler; klient->sendeEncrypted( "\3", 1 ); klient->getNachrichtEncrypted( &serverReturn, 1 ); klient->trenne(); unlock(); return 0; } klient->setSendeKey( this->schlüssel, schlüsselLän ); klient->setEmpfangKey( this->schlüssel, schlüsselLän ); verbunden = 1; unlock(); return 1; } else klient = klient->release(); } else klient = klient->release(); unlock(); return 0; } bool NewsKlient::downloadSeite( char *name ) { lock(); if( !verbunden ) verbinde(); if( !verbunden ) { unlock(); return 0; } klient->sendeEncrypted( "\5", 1 ); char ret = 0; klient->getNachrichtEncrypted( &ret, 1 ); if( ret == 1 ) { char län = (char)textLength( name ); klient->sendeEncrypted( &län, 1 ); klient->sendeEncrypted( name, län ); klient->getNachrichtEncrypted( &ret, 1 ); if( ret == 1 ) { Text *pfad = new Text( "data/tmp/news/" ); pfad->append( name ); if( DateiExistiert( pfad->getThis() ) ) DateiRemove( pfad->getThis() ); pfad->append( "/" ); int dAnz = 0; klient->getNachrichtEncrypted( (char*)&dAnz, 4 ); for( int i = 0; i < dAnz; i++ ) { char nLän = 0; klient->getNachrichtEncrypted( &nLän, 1 ); char *dName = new char[ nLän + 1 ]; dName[ nLän ] = 0; klient->getNachrichtEncrypted( dName, nLän ); Text *pf = new Text( pfad->getText() ); pf->append( dName ); delete[] dName; Datei *d = new Datei(); d->setDatei( pf ); d->erstellen(); d->open( Datei::Style::schreiben ); __int64 dGr = 0; klient->getNachrichtEncrypted( (char*)&dGr, 8 ); char buffer[ 2048 ]; while( dGr > 0 ) { int län = dGr > 2048 ? 2048 : (int)dGr; klient->getNachricht( buffer, län ); d->schreibe( buffer, län ); dGr -= län; } d->close(); d->release(); } pfad->release(); } } if( ret == 3 ) { klient->getNachrichtEncrypted( &ret, 1 ); if( ret ) { char *tmp = new char[ ret ]; klient->getNachrichtEncrypted( tmp, ret ); delete[] tmp; } unlock(); return 0; } unlock(); return 1; } bool NewsKlient::trenne( bool abmelden ) { lock(); if( !verbunden ) { unlock(); 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 ); unlock(); 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 ); unlock(); delete[] msg; } klient->trenne(); klient = klient->release(); verbunden = 0; unlock(); return 1; } // Reference Counting NewsKlient *NewsKlient::getThis() { ref++; return this; } NewsKlient *NewsKlient::release() { ref--; if( !ref ) delete this; return 0; }