#include "../KSGKlient.h"
#include "../KSGServer.h"

// Inhalt der RegisterKlient Klasse aus KSGKlient.h
// Konstruktor 
RegisterKlient::RegisterKlient()
{
    klient = 0;
    verbunden = 0;
    fehler = 0;
    brauchSchlüssel = 0;
    klientId = getKlientId();
    ref = 1;
    InitializeCriticalSection( &cs );
}

// Destruktor
RegisterKlient::~RegisterKlient() // wenn verbunden, dann trennen
{
    LOCK( &cs );
    if( klient )
    {
        char serverReturn = 0;
        if( verbunden )
        {
            if( brauchSchlüssel )
            {
                char byte = -1;
                klient->sendeVerschlüsselt( &byte, 1 );
            }
            klient->sendeVerschlüsselt( "\4", 1 );
            klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
            if( serverReturn == 3 )
            {
                char län = 0;
                klient->getNachrichtVerschlüsselt( &län, 1 );
                char *nachricht = new char[ län + 1 ];
                nachricht[ län ] = 0;
                klient->getNachrichtVerschlüsselt( nachricht, län );
                delete[]nachricht;
            }
            klient->sendeVerschlüsselt( "\3", 1 );
            klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
            klient->trenne();
        }
        else
        {
            unsigned char schlüssel[ 20 ] = { 186, 186, 179, 126, 216, 207, 123, 154, 168, 149, 51, 221, 6, 193, 160, 141, 164, 126, 44, 242 };
            klient->setSendeSchlüssel( (char*)schlüssel, 20 );
            klient->setEmpfangSchlüssel( (char*)schlüssel, 20 );
            klient->verbinde( klient->getServerPort(), klient->getServerIp() );
            klient->sendeVerschlüsselt( "\1", 1 );
            klient->sendeVerschlüsselt( (char*)&klientId, 4 );
            klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
            if( serverReturn == 3 )
            {
                char län = 0;
                klient->getNachrichtVerschlüsselt( &län, 1 );
                char *nachricht = new char[ län + 1 ];
                nachricht[ län ] = 0;
                klient->getNachrichtVerschlüsselt( nachricht, län );
                delete[]nachricht;
            }
            else
            {
                char *sl = 0;
                char slLän = getSchlüssel( &sl );
                klient->setSendeSchlüssel( sl, slLän );
                klient->setEmpfangSchlüssel( sl, slLän );
                delete[] sl;
                klient->sendeVerschlüsselt( "\4", 1 );
                klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
                if( serverReturn == 3 )
                {
                    char län = 0;
                    klient->getNachrichtVerschlüsselt( &län, 1 );
                    char *nachricht = new char[ län + 1 ];
                    nachricht[ län ] = 0;
                    klient->getNachrichtVerschlüsselt( nachricht, län );
                    delete[]nachricht;
                }
            }
            klient->sendeVerschlüsselt( "\3", 1 );
            klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
            klient->trenne();
        }
        klient = klient->release();
    }
    delete[]fehler;
    UNLOCK( &cs );
    DeleteCriticalSection( &cs );
}

// nicht constant
bool RegisterKlient::verbinde() // verbindet ich mit dem Register Server
{
    LOCK( &cs );
    if( verbunden )
    {
        UNLOCK( &cs );
        return 1;
    }
    brauchSchlüssel = 0;
    if( !klient )
    {
        char *msIp = getMainServerIp();
        unsigned short msPort = getMainServerPort();
        klient = new Klient();
        unsigned char schlüssel[ 20 ] = { 199, 164, 172, 55, 246, 16, 155, 8, 151, 176, 250, 181, 227, 133, 30, 41, 200, 26, 7, 151 };
        klient->setSendeSchlüssel( (char*)schlüssel, 20 );
        klient->setEmpfangSchlüssel( (char*)schlüssel, 20 );
        if( !klient->verbinde( msPort, msIp ) )
        {
            char *err = "Fehler beim verbinden mit dem Main Server. Bitte versuche es Später erneut.";
            delete[]fehler;
            fehler = new char[ textLänge( err ) + 1 ];
            fehler[ textLänge( err ) ] = 0;
            memcpy( fehler, err, textLänge( err ) );
            klient = klient->release();
            delete[]msIp;
            UNLOCK( &cs );
            return 0;
        }
        delete[]msIp;
        klient->sende( "\0", 1 ); // Verschlüsselung aktivieren
        klient->sendeVerschlüsselt( "\1", 1 );
        klient->sendeVerschlüsselt( (char*)&klientId, 4 );
        char serverReturn = 0;
        klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
        if( serverReturn == 3 )
        {
            char byte = 0;
            klient->getNachrichtVerschlüsselt( &byte, 1 );
            delete[]fehler;
            fehler = new char[ byte + 1 ];
            fehler[ byte ] = 0;
            klient->getNachrichtVerschlüsselt( fehler, byte );
            klient->sendeVerschlüsselt( "\3", 1 );
            klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
            klient->trenne();
            klient = klient->release();
            UNLOCK( &cs );
            return 0;
        }
        char *sl = 0;
        char slLän = getSchlüssel( &sl );
        klient->setSendeSchlüssel( sl, slLän );
        klient->setEmpfangSchlüssel( sl, slLän );
        delete[] sl;
        klient->sendeVerschlüsselt( "\6\1", 2 );
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        if( byte == 2 )
        {
            unsigned char lsIp[ 4 ];
            klient->getNachrichtVerschlüsselt( (char *)lsIp, 4 );
            unsigned short lsPort = 0;
            klient->getNachrichtVerschlüsselt( (char*)&lsPort, 2 );
            klient->sendeVerschlüsselt( "\3", 1 );
            klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
            klient->trenne();
            Text *lsIpT = new Text( "" );
            lsIpT->anhängen( (int)lsIp[ 0 ] );
            lsIpT->anhängen( "." );
            lsIpT->anhängen( (int)lsIp[ 1 ] );
            lsIpT->anhängen( "." );
            lsIpT->anhängen( (int)lsIp[ 2 ] );
            lsIpT->anhängen( "." );
            lsIpT->anhängen( (int)lsIp[ 3 ] );
            unsigned char schlüssel[ 20 ] = { 186, 186, 179, 126, 216, 207, 123, 154, 168, 149, 51, 221, 6, 193, 160, 141, 164, 126, 44, 242 };
            klient->setSendeSchlüssel( (char*)schlüssel, 20 );
            klient->setEmpfangSchlüssel( (char*)schlüssel, 20 );
            klient->verbinde( lsPort, lsIpT->getText() );
            lsIpT = lsIpT->release();
            klient->sendeVerschlüsselt( "\3", 1 );
            klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
            klient->trenne();
        }
        if( byte == 3 )
        {
            klient->getNachrichtVerschlüsselt( &byte, 1 );
            delete[]fehler;
            fehler = new char[ byte + 1 ];
            fehler[ byte ] = 0;
            klient->getNachrichtVerschlüsselt( fehler, byte );
            klient->sendeVerschlüsselt( "\3", 1 );
            klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
            klient->trenne();
            klient = klient->release();
            UNLOCK( &cs );
            return 0;
        }
    }
    unsigned char schlüssel[ 20 ] = { 186, 186, 179, 126, 216, 207, 123, 154, 168, 149, 51, 221, 6, 193, 160, 141, 164, 126, 44, 242 };
    klient->setSendeSchlüssel( (char*)schlüssel, 20 );
    klient->setEmpfangSchlüssel( (char*)schlüssel, 20 );
    if( klient->verbinde( klient->getServerPort(), klient->getServerIp() ) )
    {
        if( klient->sendeVerschlüsselt( "\1", 1 ) )
        {
            klient->sendeVerschlüsselt( (char*)&klientId, 4 );
            char serverReturn = 0;
            klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
            if( serverReturn == 3 )
            {
                char byte = 0;
                klient->getNachrichtVerschlüsselt( &byte, 1 );
                delete[]fehler;
                fehler = new char[ byte + 1 ];
                fehler[ byte ] = 0;
                klient->getNachrichtVerschlüsselt( fehler, byte );
                klient->sendeVerschlüsselt( "\3", 1 );
                klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
                klient->trenne();
                UNLOCK( &cs );
                return 0;
            }
            char *sl = 0;
            char slLän = getSchlüssel( &sl );
            klient->setSendeSchlüssel( sl, slLän );
            klient->setEmpfangSchlüssel( sl, slLän );
            delete[] sl;
            verbunden = 1;
            UNLOCK( &cs );
            return 1;
        }
        else
        {
            char *err = "Der dir zugewiesene Registrierungs Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut.";
            delete[]fehler;
            fehler = new char[ textLänge( err ) + 1 ];
            fehler[ textLänge( err ) ] = 0;
            memcpy( fehler, err, textLänge( err ) );
            klient = klient->release();
        }
    }
    else
    {
        char *err = "Der dir zugewiesene Registrierungs Server antwortet nicht. Bitte versuche es Später erneut.";
        delete[]fehler;
        fehler = new char[ textLänge( err ) + 1 ];
        fehler[ textLänge( err ) ] = 0;
        memcpy( fehler, err, textLänge( err ) );
        klient = klient->release();
    }
    UNLOCK( &cs );
    return 0;
}

bool RegisterKlient::accountErstellen( const char *name, const char *pass, const char *geheim, const char *eMail, unsigned short jahr, char monat, char tag ) // erstellt den Account
{
    if( !verbunden )
        verbinde();
    if( !verbunden )
        return 0;
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    brauchSchlüssel = 0;
    klient->sendeVerschlüsselt( "\5", 1 );
    char serverReturn = 0;
    klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
    if( serverReturn == 3 )
    {
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
        UNLOCK( &cs );
        return 0;
    }
    unsigned char län[ 4 ] = {
        (unsigned char)textLänge( name ),
        (unsigned char)textLänge( pass ),
        (unsigned char)textLänge( geheim ),
        (unsigned char)textLänge( eMail )
    };
    klient->sendeVerschlüsselt( (char*)län, 4 );
    klient->sendeVerschlüsselt( name, län[ 0 ] );
    klient->sendeVerschlüsselt( pass, län[ 1 ] );
    klient->sendeVerschlüsselt( geheim, län[ 2 ] );
    klient->sendeVerschlüsselt( eMail, län[ 3 ] );
    klient->sendeVerschlüsselt( (char*)&jahr, 2 );
    klient->sendeVerschlüsselt( &monat, 1 );
    klient->sendeVerschlüsselt( &tag, 1 );
    char byte = 0;
    klient->getNachrichtVerschlüsselt( &byte, 1 );
    if( byte == 1 )
    {
        brauchSchlüssel = 1;
        UNLOCK( &cs );
        return 1;
    }
    else if( byte == 3 )
    {
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
    }
    UNLOCK( &cs );
    return 0;
}

bool RegisterKlient::accountLöschen( const char *name, const char *pass, const char *geheim ) // löscht den Account
{
    if( !verbunden )
        verbinde();
    if( !verbunden )
        return 0;
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    brauchSchlüssel = 0;
    klient->sendeVerschlüsselt( "\6", 1 );
    char serverReturn = 0;
    klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
    if( serverReturn == 3 )
    {
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
        UNLOCK( &cs );
        return 0;
    }
    unsigned char län[ 3 ] = {
        (unsigned char)textLänge( name ),
        (unsigned char)textLänge( pass ),
        (unsigned char)textLänge( geheim )
    };
    klient->sendeVerschlüsselt( (char*)län, 3 );
    klient->sendeVerschlüsselt( name, län[ 0 ] );
    klient->sendeVerschlüsselt( pass, län[ 1 ] );
    klient->sendeVerschlüsselt( geheim, län[ 2 ] );
    char byte = 0;
    klient->getNachrichtVerschlüsselt( &byte, 1 );
    if( byte == 1 )
    {
        brauchSchlüssel = 1;
        UNLOCK( &cs );
        return 1;
    }
    else if( byte == 3 )
    {
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
    }
    UNLOCK( &cs );
    return 0;
}

int RegisterKlient::accountBestätigen( const char *name, const char *pass ) // account Bestätigung fortsetzen
{
    if( !verbunden )
        verbinde();
    if( !verbunden )
        return 0;
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    char byte = 0xE;
    klient->sendeVerschlüsselt( &byte, 1 );
    char serverReturn = 0;
    klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
    if( serverReturn == 3 )
    {
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
        UNLOCK( &cs );
        return 0;
    }
    unsigned char län[ 2 ] = {
        (unsigned char)textLänge( name ),
        (unsigned char)textLänge( pass )
    };
    klient->sendeVerschlüsselt( (char*)län, 2 );
    klient->sendeVerschlüsselt( name, län[ 0 ] );
    klient->sendeVerschlüsselt( pass, län[ 1 ] );
    byte = 0;
    klient->getNachrichtVerschlüsselt( &byte, 1 );
    brauchSchlüssel = 1;
    if( byte == 1 )
    {
        UNLOCK( &cs );
        return 1;
    }
    if( byte == 2 )
    {
        UNLOCK( &cs );
        return 2;
    }
    brauchSchlüssel = 0;
    if( byte == 3 )
    {
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
    }
    UNLOCK( &cs );
    return 0;
}

bool RegisterKlient::bestätigen( const char *schlüssel ) // bestätigt den Vorgang mit Schüssel
{
    if( !brauchSchlüssel )
        return 1;
    LOCK( &cs );
    unsigned char län = textLänge( schlüssel );
    klient->sendeVerschlüsselt( (char*)&län, 1 );
    klient->sendeVerschlüsselt( schlüssel, län );
    klient->getNachrichtVerschlüsselt( (char*)&län, 1 );
    UNLOCK( &cs );
    if( län )
    {
        brauchSchlüssel = 0;
        return 1;
    }
    else
        return 0;
}

void RegisterKlient::eMailErneutSenden() // E-Mail nochmal senden
{
    LOCK( &cs );
    char byte = -2;
    if( brauchSchlüssel )
        klient->sendeVerschlüsselt( &byte, 1 );
    UNLOCK( &cs );
}

void RegisterKlient::später() // bestätigung später abschließen
{
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    brauchSchlüssel = 0;
    UNLOCK( &cs );
}

void RegisterKlient::abbrechen() // bricht den Vorgang ab
{
    LOCK( &cs );
    if( brauchSchlüssel )
        klient->sendeVerschlüsselt( "\0", 1 );
    brauchSchlüssel = 0;
    UNLOCK( &cs );
}

bool RegisterKlient::passwortÄndern( const char *name, const char *pass, const char *geheim, const char *nPass ) // ändert das Passwort
{
    if( !verbunden )
        verbinde();
    if( !verbunden )
        return 0;
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    brauchSchlüssel = 0;
    klient->sendeVerschlüsselt( "\7", 1 );
    char serverReturn = 0;
    klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
    if( serverReturn == 3 )
    {
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
        UNLOCK( &cs );
        return 0;
    }
    unsigned char län[ 4 ] = {
        (unsigned char)textLänge( name ),
        (unsigned char)textLänge( pass ),
        (unsigned char)textLänge( nPass ),
        (unsigned char)textLänge( geheim )
    };
    klient->sendeVerschlüsselt( (char*)län, 4 );
    klient->sendeVerschlüsselt( name, län[ 0 ] );
    klient->sendeVerschlüsselt( pass, län[ 1 ] );
    klient->sendeVerschlüsselt( nPass, län[ 2 ] );
    klient->sendeVerschlüsselt( geheim, län[ 3 ] );
    char byte = 0;
    klient->getNachrichtVerschlüsselt( &byte, 1 );
    if( byte == 1 )
    {
        UNLOCK( &cs );
        return 1;
    }
    else if( byte == 3 )
    {
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
    }
    UNLOCK( &cs );
    return 0;
}

bool RegisterKlient::eMailÄndern( const char *name, const char *pass, const char *geheim, const char *nEMail ) // ändert die E-Mail Addresse
{
    if( !verbunden )
        verbinde();
    if( !verbunden )
        return 0;
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    brauchSchlüssel = 0;
    char byte = 8;
    klient->sendeVerschlüsselt( &byte, 1 );
    char serverReturn = 0;
    klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
    if( serverReturn == 3 )
    {
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
        UNLOCK( &cs );
        return 0;
    }
    unsigned char län[ 4 ] = {
        (unsigned char)textLänge( name ),
        (unsigned char)textLänge( pass ),
        (unsigned char)textLänge( geheim ),
        (unsigned char)textLänge( nEMail )
    };
    klient->sendeVerschlüsselt( (char*)län, 4 );
    klient->sendeVerschlüsselt( name, län[ 0 ] );
    klient->sendeVerschlüsselt( pass, län[ 1 ] );
    klient->sendeVerschlüsselt( geheim, län[ 2 ] );
    klient->sendeVerschlüsselt( nEMail, län[ 3 ] );
    byte = 0;
    klient->getNachrichtVerschlüsselt( &byte, 1 );
    if( byte == 1 )
    {
        UNLOCK( &cs );
        return 1;
    }
    else if( byte == 3 )
    {
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
    }
    UNLOCK( &cs );
    return 0;
}

bool RegisterKlient::geheimnisÄndern( const char *name, const char *pass, const char *geheim, const char *nGeheim ) // ändert das Geheimnis
{
    if( !verbunden )
        verbinde();
    if( !verbunden )
        return 0;
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    brauchSchlüssel = 0;
    char byte = 9;
    klient->sendeVerschlüsselt( &byte, 1 );
    char serverReturn = 0;
    klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
    if( serverReturn == 3 )
    {
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
        UNLOCK( &cs );
        return 0;
    }
    unsigned char län[ 4 ] = {
        (unsigned char)textLänge( name ),
        (unsigned char)textLänge( pass ),
        (unsigned char)textLänge( geheim ),
        (unsigned char)textLänge( nGeheim )
    };
    klient->sendeVerschlüsselt( (char*)län, 4 );
    klient->sendeVerschlüsselt( name, län[ 0 ] );
    klient->sendeVerschlüsselt( pass, län[ 1 ] );
    klient->sendeVerschlüsselt( geheim, län[ 2 ] );
    klient->sendeVerschlüsselt( nGeheim, län[ 3 ] );
    byte = 0;
    klient->getNachrichtVerschlüsselt( &byte, 1 );
    if( byte == 1 )
    {
        UNLOCK( &cs );
        return 1;
    }
    else if( byte == 3 )
    {
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
    }
    UNLOCK( &cs );
    return 0;
}

bool RegisterKlient::nameVergessen( const char *pass, const char *geheim ) // schickt den Account Namen an die Bekannte E-Mail Addresse
{
    if( !verbunden )
        verbinde();
    if( !verbunden )
        return 0;
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    brauchSchlüssel = 0;
    char byte = 0xA;
    klient->sendeVerschlüsselt( &byte, 1 );
    char serverReturn = 0;
    klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
    if( serverReturn == 3 )
    {
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
        UNLOCK( &cs );
        return 0;
    }
    unsigned char län[ 2 ] = {
        (unsigned char)textLänge( pass ),
        (unsigned char)textLänge( geheim )
    };
    klient->sendeVerschlüsselt( (char*)län, 2 );
    klient->sendeVerschlüsselt( pass, län[ 0 ] );
    klient->sendeVerschlüsselt( geheim, län[ 1 ] );
    byte = 0;
    klient->getNachrichtVerschlüsselt( &byte, 1 );
    if( byte == 1 )
    {
        UNLOCK( &cs );
        return 1;
    }
    else if( byte == 3 )
    {
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
    }
    UNLOCK( &cs );
    return 0;
}

bool RegisterKlient::passwortVergessen( const char *name, const char *geheim ) // schickt das Account Passwort an die Bekannte E-Mail Addresse
{
    if( !verbunden )
        verbinde();
    if( !verbunden )
        return 0;
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    brauchSchlüssel = 0;
    char byte = 0xB;
    klient->sendeVerschlüsselt( &byte, 1 );
    char serverReturn = 0;
    klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
    if( serverReturn == 3 )
    {
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
        UNLOCK( &cs );
        return 0;
    }
    unsigned char län[ 2 ] = {
        (unsigned char)textLänge( name ),
        (unsigned char)textLänge( geheim )
    };
    klient->sendeVerschlüsselt( (char*)län, 2 );
    klient->sendeVerschlüsselt( name, län[ 0 ] );
    klient->sendeVerschlüsselt( geheim, län[ 1 ] );
    byte = 0;
    klient->getNachrichtVerschlüsselt( &byte, 1 );
    if( byte == 1 )
    {
        UNLOCK( &cs );
        return 1;
    }
    else if( byte == 3 )
    {
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
    }
    UNLOCK( &cs );
    return 0;
}

bool RegisterKlient::geheimnisVergessen( const char *name, const char *pass ) // schickt das Account Geheimnis an die Bekannte E-Mail Addresse
{
    if( !verbunden )
        verbinde();
    if( !verbunden )
        return 0;
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    brauchSchlüssel = 0;
    char byte = 0xC;
    klient->sendeVerschlüsselt( &byte, 1 );
    char serverReturn = 0;
    klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
    if( serverReturn == 3 )
    {
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
        UNLOCK( &cs );
        return 0;
    }
    unsigned char län[ 2 ] = {
        (unsigned char)textLänge( name ),
        (unsigned char)textLänge( pass )
    };
    klient->sendeVerschlüsselt( (char*)län, 2 );
    klient->sendeVerschlüsselt( name, län[ 0 ] );
    klient->sendeVerschlüsselt( pass, län[ 1 ] );
    byte = 0;
    klient->getNachrichtVerschlüsselt( &byte, 1 );
    if( byte == 1 )
    {
        UNLOCK( &cs );
        return 1;
    }
    else if( byte == 3 )
    {
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
    }
    UNLOCK( &cs );
    return 0;
}

bool RegisterKlient::eMailVergessen( const char *name, const char *pass, const char *geheim, char **eMail ) // gibt die E-Mail Addresse des Accounts zurück
{
    if( !verbunden )
        verbinde();
    if( !verbunden )
        return 0;
    LOCK( &cs );
    if( brauchSchlüssel )
    {
        char byte = -1;
        klient->sendeVerschlüsselt( &byte, 1 );
    }
    brauchSchlüssel = 0;
    char byte2 = 0xD;
    klient->sendeVerschlüsselt( &byte2, 1 );
    char serverReturn = 0;
    klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
    if( serverReturn == 3 )
    {
        char byte = 0;
        klient->getNachrichtVerschlüsselt( &byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
        UNLOCK( &cs );
        return 0;
    }
    unsigned char län[ 3 ] = {
        (unsigned char)textLänge( name ),
        (unsigned char)textLänge( pass ),
        (unsigned char)textLänge( geheim )
    };
    klient->sendeVerschlüsselt( (char*)län, 3 );
    klient->sendeVerschlüsselt( name, län[ 0 ] );
    klient->sendeVerschlüsselt( pass, län[ 1 ] );
    klient->sendeVerschlüsselt( geheim, län[ 2 ] );
    unsigned char byte = 0;
    klient->getNachrichtVerschlüsselt( (char*)&byte, 1 );
    if( byte == 1 )
    {
        klient->getNachrichtVerschlüsselt( (char*)&byte, 1 );
        char *mail = new char[ byte + 1 ];
        mail[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( mail, byte );
        *eMail = mail;
        UNLOCK( &cs );
        return 1;
    }
    else if( byte == 3 )
    {
        klient->getNachrichtVerschlüsselt( (char*)&byte, 1 );
        delete[]fehler;
        fehler = new char[ byte + 1 ];
        fehler[ byte ] = 0;
        klient->getNachrichtVerschlüsselt( fehler, byte );
    }
    UNLOCK( &cs );
    return 0;
}

bool RegisterKlient::keepAlive() // Erhält die Verbindung aufrecht
{
    if( !verbunden )
        return 0;
    char res = 0;
    if( !TryEnterCriticalSection( &cs ) )
        return 1;
    klient->sendeVerschlüsselt( "\xF", 1 );
    klient->getNachrichtVerschlüsselt( &res, 1 );
    UNLOCK( &cs );
    if( res != 1 )
        trenne();
    return res == 1;
}

bool RegisterKlient::trenne() // trennt sich von dem Register Server
{
    if( verbunden )
    {
        LOCK( &cs );
        if( brauchSchlüssel )
        {
            char byte = -1;
            klient->sendeVerschlüsselt( &byte, 1 );
        }
        brauchSchlüssel = 0;
        klient->sendeVerschlüsselt( "\3", 1 );
        char serverReturn = 0;
        klient->getNachrichtVerschlüsselt( &serverReturn, 1 );
        klient->trenne();
        verbunden = 0;
        UNLOCK( &cs );
    }
    return 1;
}

// constant
bool RegisterKlient::istVerbunden() const // prüft, ob mit Register Server verbunden
{
    return verbunden;
}

bool RegisterKlient::vorgangBrauchBestätigung() const // prüft, ob eine Bestätigung notwendig ist
{
    return brauchSchlüssel;
}

char *RegisterKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
{
    return fehler;
}

// Reference Counting
RegisterKlient *RegisterKlient::getThis()
{
    ref++;
    return this;
}

RegisterKlient *RegisterKlient::release()
{
    ref--;
    if( !ref )
        delete this;
    return 0;
}