#include "ErhaltungServer.h"
#include <iostream>
#include <Klient.h>
#include <Globals.h>
#ifndef WIN32
#include <unistd.h>
#define Sleep( x )   usleep( (x) * 1000 )
#endif

// Inhalt der ErhaltungServer Klasse aus ErhaltungServer.h
// Konstruktor
ErhaltungServer::ErhaltungServer( InitDatei *zIni )
	: Thread()
{
	Network::Start( 100 );
	std::cout << "ES: Verbindung mit Datenbank wird hergestellt...\n";
	db = new ESDatenbank( zIni );
	empfangen = 0;
	gesendet = 0;
	clients = 0;
	fehler = new Text();
	ini = zIni->getThis();
	id = *zIni->zWert( "ServerId" );
	server = new Server();
	aServer = new Server();
	std::cout << "ES: Starten des Admin Servers...\n";
	if( !aServer->verbinde( (unsigned short)TextZuInt( ini->zWert( "AdminServerPort" )->getText(), 10 ), 10 ) )
	{
		std::cout << "ES: Der Admin Server konnte nicht gestartet werden. Das Programm wird beendet.\n";
		exit( 1 );
	}
	db->setServerStatus( id, 2 );
	end = 0;
	nichtPausiert = 0;
	ref = 1;
	if( zIni->zWert( "Aktiv" )->istGleich( "TRUE" ) )
	{
		serverStarten();
		serverFortsetzen();
	}
}

// Destruktor
ErhaltungServer::~ErhaltungServer()
{
	fehler->release();
	server->trenne();
	server->release();
	aServer->trenne();
	aServer->release();
	ini->release();
	db->release();
}

void ErhaltungServer::runn()
{
	while( !end )
	{
		SKlient *klient;
		klient = aServer->getKlient();
		if( end && klient )
		{
			klient->trenne();
			klient = klient->release();
			Sleep( 1000 );
			return;
		}
		if( !klient )
			return;
		ESAKlient *clHandle = new ESAKlient( klient, getThis() );
		clHandle->start();
	}
}

void ErhaltungServer::thread()
{
	while( 1 )
	{
		SKlient *klient;
		klient = server->getKlient();
		if( !klient )
			break;
		Framework::getThreadRegister()->cleanUpClosedThreads();
		ESKlient *clHandle = new ESKlient( klient, getThis() );
		clients++;
		clHandle->start();
	}
}

void ErhaltungServer::close()
{
	db->setServerStatus( id, 1 );
	server->trenne();
#ifdef WIN32
	warteAufThread( 1000 );
#endif
	ende();
	run = 0;
	end = 1;
	Klient *klient = new Klient();
	klient->verbinde( aServer->getPort(), "127.0.0.1" );
	Sleep( 500 );
	aServer->trenne();
	klient->release();
}

// nicht constant
bool ErhaltungServer::serverStarten()
{
	if( nichtPausiert )
	{
		fehler->setText( "Der Server konnte nicht gestartet werden: Der Server läuft bereits." );
		return 0;
	}
	if( server )
		server->release();
	server = new Server();
	if( server->verbinde( (unsigned short)TextZuInt( ini->zWert( "ServerPort" )->getText(), 10 ), 10 ) )
	{
		nichtPausiert = 1;
		start();
		return 1;
	}
	else
	{
		serverBeenden();
		fehler->setText( "Der Server konnte nicht gestartet werden: Eventuell ist der Port in benutzung." );
		return 0;
	}
}

bool ErhaltungServer::serverPause()
{
	if( !nichtPausiert )
	{
		fehler->setText( "Der Server konnte nicht pausiert werden: Der Server läuft nicht." );
		return 0;
	}
	if( !db->setServerStatus( id, 2 ) )
	{
		fehler->setText( "Der Server konnte nicht pausiert werden: " );
		fehler->append( db->getLetzterFehler() );
		return 0;
	}
	return 1;
}

bool ErhaltungServer::serverFortsetzen()
{
	if( !nichtPausiert )
	{
		fehler->setText( "Der Server konnte nicht fortgesetzt werden: Der Server läuft nicht." );
		return 0;
	}
	if( !db->setServerStatus( id, 3 ) )
	{
		fehler->setText( "Der Server konnte nicht fortgesetzt werden: " );
		fehler->append( db->getLetzterFehler() );
		return 0;
	}
	return 1;
}

bool ErhaltungServer::serverBeenden()
{
	if( !nichtPausiert )
	{
		fehler->setText( "Der Server konnte nicht beendet werden: Der Server läuft nicht." );
		return 0;
	}
	if( db->serverIstNichtPausiert( id ) )
	{
		fehler->setText( "Der Server konnte nicht beendet werden: Der Server muss erst pausiert werden." );
		return 0;
	}
	nichtPausiert = 0;
	if( server )
		server->trenne();
#ifdef WIN32
	warteAufThread( 1000 );
#endif
	ende();
	return 1;
}

bool ErhaltungServer::setMaxKlients( unsigned char mc )
{
	if( !db->setMaxClients( id, mc ) )
	{
		fehler->setText( "Die maximale Anzahl der Clients konnte nicht gesetzt werden:\n" );
		fehler->append( db->getLetzterFehler() );
		return 0;
	}
	ini->setWert( "MaxClients", Text() += mc );
	return 1;
}

void ErhaltungServer::addGesendet( int bytes )
{
	gesendet += bytes;
}

void ErhaltungServer::addEmpfangen( int bytes )
{
	empfangen += bytes;
}

void ErhaltungServer::clientTrennung()
{
	clients--;
}

// constant
bool ErhaltungServer::istAn() const
{
	return db->serverIstNichtPausiert( id );
}

Server *ErhaltungServer::zServer() const
{
	return server;
}

ESDatenbank *ErhaltungServer::zDB() const
{
	return db;
}

bool ErhaltungServer::hatClients() const
{
	return clients > 0;
}

int ErhaltungServer::getId() const
{
	return id;
}

char *ErhaltungServer::getLetzterFehler() const
{
	return fehler->getText();
}

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

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


// Inhalt der RSAKlient Klasse aus RegisterServer.h
// Konstruktor 
ESAKlient::ESAKlient( SKlient *klient, ErhaltungServer *es )
	: Thread()
{
	this->klient = klient;
	unsigned char key[ 20 ] = { 139, 91, 188, 189, 188, 165, 72, 233, 199, 10, 253, 197, 61, 125, 201, 251, 37, 22, 161, 187 };
	klient->setSendeKey( (char*)key, 20 );
	klient->setEmpfangKey( (char*)key, 20 );
	name = new Text( "" );
	passwort = new Text( "" );
	adminId = 0;
	version = 0;
	this->es = es;
}

// Destruktor 
ESAKlient::~ESAKlient()
{
	klient->trenne();
	klient->release();
	es->release();
	name->release();
	passwort->release();
}

// nicht constant 
void ESAKlient::thread()
{
	while( 1 )
	{
		char c = 0;
		if( !klient->getNachrichtEncrypted( &c, 1 ) )
			break;
		else
		{
			bool br = 0;
			switch( c )
			{
			case 1: // Login
				if( 1 )
				{
					klient->sendeEncrypted( "\1", 1 );
					char nLen = 0;
					klient->getNachrichtEncrypted( &nLen, 1 );
					char *n = new char[ nLen + 1 ];
					n[ (int)nLen ] = 0;
					if( nLen )
						klient->getNachrichtEncrypted( n, nLen );
					char pLen = 0;
					klient->getNachrichtEncrypted( &pLen, 1 );
					char *p = new char[ pLen + 1 ];
					p[ (int)pLen ] = 0;
					if( pLen )
						klient->getNachrichtEncrypted( p, pLen );
					int adminId = es->zDB()->istAdministrator( n, p );
					if( adminId )
					{
						klient->sendeEncrypted( "\1", 1 );
						name->setText( n );
						passwort->setText( p );
						this->adminId = adminId;
					}
					else
						errorZuKlient( "Falsche Kombination aus Name und Passwort." );
					delete[] n;
					delete[] p;
				}
				break;
			case 2: // Logout
				adminId = 0;
				name->setText( "" );
				passwort->setText( "" );
				klient->sendeEncrypted( "\1", 1 );
				break;
			case 3: // Trennen
				br = 1;
				klient->sendeEncrypted( "\1", 1 );
				break;
			case 4: // Server starten
				if( !adminId )
					errorZuKlient( "Du musst dich einloggen." );
				else
				{
					if( es->zDB()->adminHatRecht( adminId, Admin_Recht::LSStarten ) )
					{
						if( !es->serverStarten() )
						{
							Text *err = new Text();
							err->append( es->getLetzterFehler() );
							errorZuKlient( err->getText() );
							err->release();
						}
						else
							klient->sendeEncrypted( "\1", 1 );
					}
					else
						errorZuKlient( "Du bist nicht berechtigt den Server zu starten." );
				}
				break;
			case 5: // Server beenden
				if( !adminId )
					errorZuKlient( "Du musst dich einloggen." );
				else
				{
					if( es->zDB()->adminHatRecht( adminId, Admin_Recht::LSBeenden ) )
					{
						if( es->serverBeenden() )
							klient->sendeEncrypted( "\1", 1 );
						else
						{
							Text *err = new Text();
							err->append( es->getLetzterFehler() );
							errorZuKlient( err->getText() );
							err->release();
						}
					}
					else
						errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
				}
				break;
			case 6: // Programm Schließen
				if( !adminId )
					errorZuKlient( "Du musst dich einloggen." );
				else
				{
					bool ok = 0;
					if( es->isRunning() )
					{
						if( es->zDB()->adminHatRecht( adminId, Admin_Recht::LSBeenden ) )
						{
							if( es->serverBeenden() )
								ok = 1;
							else
							{
								Text *err = new Text();
								err->append( es->getLetzterFehler() );
								errorZuKlient( err->getText() );
								err->release();
							}
						}
						else
							errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
					}
					else
						ok = 1;
					if( ok && es->hatClients() )
					{
						errorZuKlient( "Es sind noch Klients Online. Bitte versuche es später erneut." );
						break;
					}
					if( ok )
					{
						klient->sendeEncrypted( "\1", 1 );
						std::cout << "IS: Der Server wird von Benutzer " << adminId << " heruntergefahren.\n";
						es->close();
						br = 1;
					}
				}
				break;
			case 7: // Progtamm abstürzen
				if( !adminId )
					errorZuKlient( "Du musst dich einloggen." );
				else
				{
					bool ok = 0;
					if( es->isRunning() )
					{
						if( es->zDB()->adminHatRecht( adminId, Admin_Recht::LSBeenden ) )
						{
							es->serverBeenden();
							ok = 1;
						}
						else
							errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
					}
					else
						ok = 1;
					if( ok )
					{
						klient->sendeEncrypted( "\1", 1 );
						std::cout << "IS: Der Server wurde von Benutzer " << adminId << " terminiert.\n";
						es->close();
						br = 1;
					}
				}
				break;
			case 8: // Status Frage
				if( 1 )
				{
					char status = 0;
					if( es->isRunning() )
					{
						status = 1;
						if( es->istAn() )
							status = 2;
					}
					klient->sendeEncrypted( "\1", 1 );
					klient->sendeEncrypted( &status, 1 );
				}
				break;
			case 9: // Server pausieren
				if( !adminId )
					errorZuKlient( "Du musst dich einloggen." );
				else
				{
					klient->sendeEncrypted( "\1", 1 );
					char pause = 0;
					klient->getNachrichtEncrypted( &pause, 1 );
					if( es->zDB()->adminHatRecht( adminId, Admin_Recht::LSPausieren ) )
					{
						bool ok = 0;
						if( pause )
							ok = es->serverPause();
						else
							ok = es->serverFortsetzen();
						if( ok )
							klient->sendeEncrypted( "\1", 1 );
						else
						{
							Text *err = new Text();
							err->append( es->getLetzterFehler() );
							errorZuKlient( err->getText() );
							err->release();
						}
					}
					else
					{
						if( pause )
							errorZuKlient( "Du bist nicht berechtigt den Server zu pausieren." );
						else
							errorZuKlient( "Du bist nicht berechtigt den Server fortzusetzen." );
					}
				}
				break;
			case 0xA: // maximale Anzahl der Clients setzen
				if( !adminId )
					errorZuKlient( "Du musst dich einloggen." );
				else
				{
					klient->sendeEncrypted( "\1", 1 );
					int maxC = 0;
					klient->getNachrichtEncrypted( (char*)&maxC, 4 );
					if( es->zDB()->adminHatRecht( adminId, Admin_Recht::LSMCChange ) )
					{
						if( es->setMaxKlients( (unsigned char)maxC ) )
							klient->sendeEncrypted( "\1", 1 );
						else
						{
							Text *err = new Text();
							err->append( es->getLetzterFehler() );
							errorZuKlient( err->getText() );
							err->release();
						}
					}
					else
						errorZuKlient( "Du bist nicht berechtigt die maximale Anzahl der Clients zu verändern." );
				}
				break;
			default:
				errorZuKlient( "Unbekannte Nachricht!" );
				break;
			}
			if( br )
				break;
			es->addEmpfangen( klient->getDownloadBytes( 1 ) );
			es->addGesendet( klient->getUploadBytes( 1 ) );
		}
	}
	es->addEmpfangen( klient->getDownloadBytes( 1 ) );
	es->addGesendet( klient->getUploadBytes( 1 ) );
	delete this;
}

void ESAKlient::errorZuKlient( const char *nachricht ) const // sendet eine Fehlernachricht zum Klient
{
	klient->sendeEncrypted( "\3", 1 );
	char len = (char)textLength( nachricht );
	klient->sendeEncrypted( &len, 1 );
	klient->sendeEncrypted( nachricht, len );
}


// Inhalt der ESKThread Klasse aus ErhaltungServer.h
// Konstruktor
ESKThread::ESKThread( ESKlient *zKlient )
{
	this->zKlient = zKlient;
	ref = 1;
}

// Destruktor
ESKThread::~ESKThread()
{
	ende();
}

// nicht constant
void ESKThread::thread()
{
	while( 1 )
	{
		if( !zKlient->erhalten() )
			break;
		Sleep( 2000 );
	}
	run = 0;
}

// constant

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

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


// Inhalt der ESKlient Klasse aus ErhaltungServer.h
// Konstruktor
ESKlient::ESKlient( SKlient *klient, ErhaltungServer *es )
{
	th = new ESKThread( this );
	this->klient = klient;
	unsigned char key[ 20 ] = { 207, 242, 142, 161, 148, 107, 131, 33, 172, 68, 91, 169, 81, 106, 69, 131, 207, 56, 166, 248 };
	klient->setSendeKey( (char*)key, 20 );
	klient->setEmpfangKey( (char*)key, 20 );
	zeit = new ZeitMesser();
	zeit->messungStart();
	sekunden = 0;
	letzteErhaltung = 0;
	abgemeldet = 0;
	klientNummer = 0;
	this->es = es;
	encrypted = 0;
}

// Destruktor
ESKlient::~ESKlient()
{
	th->release();
	es->clientTrennung();
	es->release();
	klient->release();
	zeit->release();
}

// nicht constant
bool ESKlient::erhalten()
{
	char ret = 0;
	if( encrypted )
	{
		if( !klient->sendeEncrypted( "\1", 1 ) )
			return 0;
		if( !klient->getNachrichtEncrypted( &ret, 1 ) )
			return 0;
		if( ret == 1 )
		{
			klient->sendeEncrypted( "\1", 1 );
			abgemeldet = 1;
			letzteErhaltung = -5;
			return 0;
		}
	}
	else
	{
		if( !klient->sende( "\1", 1 ) )
			return 0;
		if( !klient->getNachricht( &ret, 1 ) )
			return 0;
		if( ret == 1 )
		{
			klient->sende( "\1", 1 );
			abgemeldet = 1;
			letzteErhaltung = -5;
			return 0;
		}
	}
	letzteErhaltung = sekunden;
	return 1;
}

void ESKlient::thread()
{
	bool erhalten = 0;
	bool br = 0;
	while( 1 )
	{
		char c = 0;
		if( ( !encrypted && klient->getNachricht( &c, 1 ) ) || ( encrypted && klient->getNachrichtEncrypted( &c, 1 ) ) )
		{
			if( !c )
				encrypted = 1;
			if( c == 1 ) // Klient hat sich verbunden
			{
				if( encrypted )
					klient->getNachrichtEncrypted( (char*)&klientNummer, 4 );
				else
					klient->getNachricht( (char*)&klientNummer, 4 );
				if( !es->zDB()->proveKlient( klientNummer, es->getId() ) )
				{
					klientNummer = 0;
					errorZuKlient( "Du bist nicht für diesen Server eingetragen" );
				}
				else
				{
					if( encrypted )
					{
						Text *key = es->zDB()->getKlientKey( klientNummer );
						if( !key )
							errorZuKlient( "Es konnte kein Schlüssel ermittelt werden." );
						else
						{
							klient->sendeEncrypted( "\1", 1 );
							klient->setEmpfangKey( *key, key->getLength() );
							klient->setSendeKey( *key, key->getLength() );
							key->release();
						}
					}
					else
						klient->sende( "\1", 1 );
					erhalten = 1;
					th->start();
					br = 1;
				}
			}
            else if( c == 3 )
			{
				if( encrypted )
					klient->sendeEncrypted( "\1", 1 );
				else
					klient->sende( "\1", 1 );
				br = 1;
			}
            else
            {

            }
		}
		else
			br = 1;
		if( br )
			break;
		es->addEmpfangen( klient->getDownloadBytes( 1 ) );
		es->addGesendet( klient->getUploadBytes( 1 ) );
	}
	while( erhalten )
	{
		Sleep( 1000 );
		zeit->messungEnde();
		zeit->messungStart();
		sekunden += zeit->getSekunden();
		if( letzteErhaltung <= sekunden - 60 ) // erhaltung time out
		{
			if( !abgemeldet )
			{
				std::cout << "IS: Der Klient " << klientNummer << " antwortet nicht mehr.\n";
				std::cout.flush();
			}
			int accountId = es->zDB()->clientIstEingeloggt( klientNummer );
			if( accountId )
			{
				Array< int > *ret = new Array< int >();
				int anzahl = es->zDB()->logoutKlient( klientNummer, ret );
				if( anzahl > 0 )
				{
					int jetzt = 0;
					int chAnz = ret->get( jetzt );
					jetzt++;
					for( int i = 0; i < chAnz; i++ )
					{
						int chatroomId = ret->get( jetzt );
						jetzt++;
						if( chatroomId )
						{
							ESGWeiterleitung *weiter = new ESGWeiterleitung( es->getThis() );
							weiter->spielerLeavesChatroom( chatroomId, accountId );
							weiter->release();
							if( ret->get( jetzt ) )
							{
								ESGWeiterleitung *weiter = new ESGWeiterleitung( es->getThis() );
								weiter->setChatroomAdmin( chatroomId, es->zDB()->getChatroomAdmin( chatroomId ) );
								weiter->release();
							}
							jetzt++;
						}
					}
					if( ret->get( jetzt ) == 1 )
					{
						jetzt++;
						ESGWeiterleitung *weiter = new ESGWeiterleitung( es->getThis() );
						weiter->spielErstelltAbbrechen( ret->get( jetzt ) );
						weiter->release();
					}
					jetzt++;
					if( ret->get( jetzt ) == 1 )
					{
						jetzt++;
						int gruppeId = ret->get( jetzt );
						ESGWeiterleitung *weiter = new ESGWeiterleitung( es->getThis() );
						weiter->spielerLeavesGruppe( gruppeId, accountId );
						weiter->release();
						jetzt++;
						if( ret->get( jetzt ) )
						{
							ESGWeiterleitung *weiter = new ESGWeiterleitung( es->getThis() );
							weiter->setGruppeAdmin( gruppeId, es->zDB()->getGruppeAdmin( gruppeId ) );
							weiter->release();
						}
					}
					else if( ret->get( jetzt ) == 2 )
					{
						jetzt++;
						int gruppeId = ret->get( jetzt );
						ESGWeiterleitung *weiter = new ESGWeiterleitung( es->getThis() );
						weiter->kickSpielerAusGruppe( gruppeId );
						weiter->release();
					}
				}
				ret->release();
				es->zDB()->unregisterKlient( klientNummer, es->getId() );
				ESGWeiterleitung *weiter = new ESGWeiterleitung( es->getThis() );
				weiter->patchServerKlientAbsturz( klientNummer );
				weiter->registerServerKlientAbsturz( klientNummer );
				weiter->loginServerKlientAbsturz( klientNummer );
				weiter->informationServerKlientAbsturz( klientNummer );
				weiter->chatServerKlientAbsturz( klientNummer );
				weiter->anmeldungServerKlientAbsturz( klientNummer );
				weiter->spielServerKlientAbsturz( klientNummer );
				weiter->shopServerKlientAbsturz( klientNummer );
				weiter->historieServerKlientAbsturz( klientNummer );
                weiter->newsServerKlientAbsturz( klientNummer );
                weiter->kartenServerKlientAbsturz( klientNummer );
                weiter->editorServerKlientAbsturz( klientNummer );
                weiter->minigameServerKlientAbsturz( klientNummer );
				weiter->release();
				es->zDB()->removeKlient( klientNummer );
			}
			else
			{
				es->zDB()->unregisterKlient( klientNummer, es->getId() );
				if( !abgemeldet )
				{
					ESGWeiterleitung *weiter = new ESGWeiterleitung( es->getThis() );
					weiter->patchServerKlientAbsturz( klientNummer );
					weiter->registerServerKlientAbsturz( klientNummer );
					weiter->loginServerKlientAbsturz( klientNummer );
					weiter->informationServerKlientAbsturz( klientNummer );
					weiter->chatServerKlientAbsturz( klientNummer );
					weiter->anmeldungServerKlientAbsturz( klientNummer );
					weiter->spielServerKlientAbsturz( klientNummer );
					weiter->shopServerKlientAbsturz( klientNummer );
					weiter->historieServerKlientAbsturz( klientNummer );
                    weiter->newsServerKlientAbsturz( klientNummer );
                    weiter->kartenServerKlientAbsturz( klientNummer );
                    weiter->editorServerKlientAbsturz( klientNummer );
                    weiter->minigameServerKlientAbsturz( klientNummer );
					weiter->release();
					es->zDB()->removeKlient( klientNummer );
				}
			}
			break;
		}
	}
	delete this;
}

// constant
void ESKlient::errorZuKlient( const char *nachricht ) const
{
	if( encrypted )
	{
		klient->sendeEncrypted( "\3", 1 );
		char len = (char)textLength( nachricht );
		klient->sendeEncrypted( &len, 1 );
		klient->sendeEncrypted( nachricht, len );
	}
	else
	{
		klient->sende( "\3", 1 );
		char len = (char)textLength( nachricht );
		klient->sende( &len, 1 );
		klient->sende( nachricht, len );
	}
}


// Inhalt der ESGWeiterleitung Klasse aus ErhaltungServer.h
// Konstruktor
ESGWeiterleitung::ESGWeiterleitung( ErhaltungServer *es )
{
	this->es = es;
	ref = 1;
}

// Destruktor
ESGWeiterleitung::~ESGWeiterleitung()
{
	es->release();
}

// nicht constant
bool ESGWeiterleitung::patchServerKlientAbsturz( int klientId )
{
	Text *ip = new Text();
	int port = 0;
	if( !es->zDB()->getPatchServer( klientId, ip, &port ) )
	{
		ip->release();
		return 0;
	}
	Klient *k = new Klient();
	unsigned char key[ 20 ] = { 102, 139, 140, 143, 52, 52, 194, 167, 97, 106, 23, 72, 170, 121, 213, 178, 28, 28, 124, 185 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	k->verbinde( (unsigned short)port, ip->getText() );
	ip->release();
	char ret = 0;
	k->sende( "\0", 1 ); // Verkeyung aktivieren
	k->sendeEncrypted( "\2\2", 2 );
	k->sendeEncrypted( (char*)&klientId, 4 );
	k->getNachrichtEncrypted( &ret, 1 );
	bool erf = ret == 1;
	k->sendeEncrypted( "\3", 1 );
	k->getNachrichtEncrypted( &ret, 1 );
	es->addEmpfangen( k->getDownloadBytes( 1 ) );
	es->addGesendet( k->getUploadBytes( 1 ) );
	k->trenne();
	k->release();
	return erf;
}

bool ESGWeiterleitung::registerServerKlientAbsturz( int klientId )
{
	Text *ip = new Text();
	int port = 0;
	if( !es->zDB()->getRegisterServer( klientId, ip, &port ) )
	{
		ip->release();
		return 0;
	}
	Klient *k = new Klient();
	unsigned char key[ 20 ] = { 186, 186, 179, 126, 216, 207, 123, 154, 168, 149, 51, 221, 6, 193, 160, 141, 164, 126, 44, 242 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	k->verbinde( (unsigned short)port, ip->getText() );
	ip->release();
	char ret = 0;
	k->sendeEncrypted( "\2\2", 2 );
	k->sendeEncrypted( (char*)&klientId, 4 );
	k->getNachrichtEncrypted( &ret, 1 );
	bool erf = ret == 1;
	k->sendeEncrypted( "\3", 1 );
	k->getNachrichtEncrypted( &ret, 1 );
	es->addEmpfangen( k->getDownloadBytes( 1 ) );
	es->addGesendet( k->getUploadBytes( 1 ) );
	k->trenne();
	k->release();
	return erf;
}

bool ESGWeiterleitung::loginServerKlientAbsturz( int klientId )
{
	Text *ip = new Text();
	int port = 0;
	if( !es->zDB()->getLoginServer( klientId, ip, &port ) )
	{
		ip->release();
		return 0;
	}
	Klient *k = new Klient();
	unsigned char key[ 20 ] = { 143, 166, 245, 235, 76, 75, 116, 80, 26, 178, 142, 176, 109, 53, 106, 222, 223, 55, 139, 111 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	k->verbinde( (unsigned short)port, ip->getText() );
	ip->release();
	char ret = 0;
	k->sendeEncrypted( "\2\2", 2 );
	k->sendeEncrypted( (char*)&klientId, 4 );
	k->getNachrichtEncrypted( &ret, 1 );
	bool erf = ret == 1;
	k->sendeEncrypted( "\3", 1 );
	k->getNachrichtEncrypted( &ret, 1 );
	es->addEmpfangen( k->getDownloadBytes( 1 ) );
	es->addGesendet( k->getUploadBytes( 1 ) );
	k->trenne();
	k->release();
	return erf;
}

bool ESGWeiterleitung::informationServerKlientAbsturz( int klientId )
{
	Text *ip = new Text();
	int port = 0;
	if( !es->zDB()->getInformationServer( klientId, ip, &port ) )
	{
		ip->release();
		return 0;
	}
	Klient *k = new Klient();
	unsigned char key[ 20 ] = { 231, 246, 125, 32, 88, 172, 229, 223, 246, 138, 74, 64, 142, 245, 217, 218, 162, 62, 103, 50 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	k->verbinde( (unsigned short)port, ip->getText() );
	ip->release();
	char ret = 0;
	k->sendeEncrypted( "\2\2", 2 );
	k->sendeEncrypted( (char*)&klientId, 4 );
	k->getNachrichtEncrypted( &ret, 1 );
	bool erf = ret == 1;
	k->sendeEncrypted( "\3", 1 );
	k->getNachrichtEncrypted( &ret, 1 );
	es->addEmpfangen( k->getDownloadBytes( 1 ) );
	es->addGesendet( k->getUploadBytes( 1 ) );
	k->trenne();
	k->release();
	return erf;
}

bool ESGWeiterleitung::chatServerKlientAbsturz( int klientId )
{
	Text *ip = new Text();
	int port = 0;
	if( !es->zDB()->getChatServer( klientId, ip, &port ) )
	{
		ip->release();
		return 0;
	}
	Klient *k = new Klient();
	unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	k->verbinde( (unsigned short)port, ip->getText() );
	ip->release();
	char ret = 0;
	k->sendeEncrypted( "\2\2", 2 );
	k->sendeEncrypted( (char*)&klientId, 4 );
	k->getNachrichtEncrypted( &ret, 1 );
	bool erf = ret == 1;
	k->sendeEncrypted( "\3", 1 );
	k->getNachrichtEncrypted( &ret, 1 );
	es->addEmpfangen( k->getDownloadBytes( 1 ) );
	es->addGesendet( k->getUploadBytes( 1 ) );
	k->trenne();
	k->release();
	return erf;
}

bool ESGWeiterleitung::anmeldungServerKlientAbsturz( int klientId )
{
	Text *ip = new Text();
	int port = 0;
	if( !es->zDB()->getAnmeldungServer( klientId, ip, &port ) )
	{
		ip->release();
		return 0;
	}
	Klient *k = new Klient();
	unsigned char key[ 20 ] = { 158, 10, 37, 155, 117, 58, 28, 197, 132, 76, 252, 83, 84, 222, 11, 125, 240, 218, 25, 201 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	k->verbinde( (unsigned short)port, ip->getText() );
	ip->release();
	char ret = 0;
	k->sendeEncrypted( "\2\2", 2 );
	k->sendeEncrypted( (char*)&klientId, 4 );
	k->getNachrichtEncrypted( &ret, 1 );
	bool erf = ret == 1;
	k->sendeEncrypted( "\3", 1 );
	k->getNachrichtEncrypted( &ret, 1 );
	es->addEmpfangen( k->getDownloadBytes( 1 ) );
	es->addGesendet( k->getUploadBytes( 1 ) );
	k->trenne();
	k->release();
	return erf;
}

bool ESGWeiterleitung::spielServerKlientAbsturz( int klientId )
{
	Text *ip = new Text();
	int port = 0;
	if( !es->zDB()->getSpielServer( klientId, ip, &port ) )
	{
		ip->release();
		return 0;
	}
	Klient *k = new Klient();
	unsigned char key[ 20 ] = { 253, 234, 211, 132, 121, 230, 95, 145, 201, 13, 43, 77, 153, 223, 253, 69, 234, 43, 52, 99 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	k->verbinde( (unsigned short)port, ip->getText() );
	ip->release();
	char ret = 0;
	k->sendeEncrypted( "\2\2", 2 );
	k->sendeEncrypted( (char*)&klientId, 4 );
	k->getNachrichtEncrypted( &ret, 1 );
	bool erf = ret == 1;
	k->sendeEncrypted( "\3", 1 );
	k->getNachrichtEncrypted( &ret, 1 );
	es->addEmpfangen( k->getDownloadBytes( 1 ) );
	es->addGesendet( k->getUploadBytes( 1 ) );
	k->trenne();
	k->release();
	return erf;
}

bool ESGWeiterleitung::shopServerKlientAbsturz( int klientId )
{
	Text *ip = new Text();
	int port = 0;
	if( !es->zDB()->getShopServer( klientId, ip, &port ) )
	{
		ip->release();
		return 0;
	}
	Klient *k = new Klient();
	unsigned char key[ 20 ] = { 218, 226, 231, 216, 68, 63, 132, 155, 49, 235, 239, 0, 19, 23, 116, 244, 235, 21, 189, 53 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	k->verbinde( (unsigned short)port, ip->getText() );
	ip->release();
	char ret = 0;
	k->sendeEncrypted( "\2\2", 2 );
	k->sendeEncrypted( (char*)&klientId, 4 );
	k->getNachrichtEncrypted( &ret, 1 );
	bool erf = ret == 1;
	k->sendeEncrypted( "\3", 1 );
	k->getNachrichtEncrypted( &ret, 1 );
	es->addEmpfangen( k->getDownloadBytes( 1 ) );
	es->addGesendet( k->getUploadBytes( 1 ) );
	k->trenne();
	k->release();
	return erf;
}

bool ESGWeiterleitung::historieServerKlientAbsturz( int klientId )
{
	Text *ip = new Text();
	int port = 0;
	if( !es->zDB()->getHistorieServer( klientId, ip, &port ) )
	{
		ip->release();
		return 0;
	}
	Klient *k = new Klient();
	unsigned char key[ 20 ] = { 207, 30, 72, 46, 30, 50, 56, 213, 82, 107, 14, 201, 149, 58, 110, 138, 228, 241, 52, 54 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	k->verbinde( (unsigned short)port, ip->getText() );
	ip->release();
	char ret = 0;
	k->sendeEncrypted( "\2\2", 2 );
	k->sendeEncrypted( (char*)&klientId, 4 );
	k->getNachrichtEncrypted( &ret, 1 );
	bool erf = ret == 1;
	k->sendeEncrypted( "\3", 1 );
	k->getNachrichtEncrypted( &ret, 1 );
	es->addEmpfangen( k->getDownloadBytes( 1 ) );
	es->addGesendet( k->getUploadBytes( 1 ) );
	k->trenne();
	k->release();
	return erf;
}

bool ESGWeiterleitung::newsServerKlientAbsturz( int klientId )
{
	Text *ip = new Text();
	int port = 0;
	if( !es->zDB()->getNewsServer( klientId, ip, &port ) )
	{
		ip->release();
		return 0;
	}
	Klient *k = new Klient();
	unsigned char key[ 20 ] = { 4, 150, 243, 145, 204, 71, 253, 88, 4, 51, 189, 207, 189, 248, 231, 40, 106, 7, 182, 5 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	k->verbinde( (unsigned short)port, ip->getText() );
	ip->release();
	char ret = 0;
	k->sendeEncrypted( "\2\2", 2 );
	k->sendeEncrypted( (char*)&klientId, 4 );
	k->getNachrichtEncrypted( &ret, 1 );
	bool erf = ret == 1;
	k->sendeEncrypted( "\3", 1 );
	k->getNachrichtEncrypted( &ret, 1 );
	es->addEmpfangen( k->getDownloadBytes( 1 ) );
	es->addGesendet( k->getUploadBytes( 1 ) );
	k->trenne();
	k->release();
	return erf;
}

bool ESGWeiterleitung::kartenServerKlientAbsturz( int klientId )
{
    Text *ip = new Text();
    int port = 0;
    if( !es->zDB()->getKartenServer( klientId, ip, &port ) )
    {
        ip->release();
        return 0;
    }
    Klient *k = new Klient();
    unsigned char key[ 20 ] = { 24, 15, 53, 87, 38, 73, 154, 38, 246, 90, 39, 133, 11, 199, 22, 80, 26, 132, 95, 54 };
    k->setSendeKey( (char*)key, 20 );
    k->setEmpfangKey( (char*)key, 20 );
    k->verbinde( (unsigned short)port, ip->getText() );
    ip->release();
    char ret = 0;
    k->sendeEncrypted( "\2\2", 2 );
    k->sendeEncrypted( (char*)&klientId, 4 );
    k->getNachrichtEncrypted( &ret, 1 );
    bool erf = ret == 1;
    k->sendeEncrypted( "\3", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    es->addEmpfangen( k->getDownloadBytes( 1 ) );
    es->addGesendet( k->getUploadBytes( 1 ) );
    k->trenne();
    k->release();
    return erf;
}

bool ESGWeiterleitung::editorServerKlientAbsturz( int klientId )
{
    Text *ip = new Text();
    int port = 0;
    if( !es->zDB()->getEditorServer( klientId, ip, &port ) )
    {
        ip->release();
        return 0;
    }
    Klient *k = new Klient();
    unsigned char key[ 20 ] = { 55, 124, 19, 204, 23, 5, 59, 75, 247, 138, 119, 111, 57, 250, 206, 187, 165, 6, 247, 151 };
    k->setSendeKey( (char*)key, 20 );
    k->setEmpfangKey( (char*)key, 20 );
    k->verbinde( (unsigned short)port, ip->getText() );
    ip->release();
    char ret = 0;
    k->sendeEncrypted( "\2\2", 2 );
    k->sendeEncrypted( (char*)&klientId, 4 );
    k->getNachrichtEncrypted( &ret, 1 );
    bool erf = ret == 1;
    k->sendeEncrypted( "\3", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    es->addEmpfangen( k->getDownloadBytes( 1 ) );
    es->addGesendet( k->getUploadBytes( 1 ) );
    k->trenne();
    k->release();
    return erf;
}

bool ESGWeiterleitung::minigameServerKlientAbsturz( int klientId )
{
    Text *ip = new Text();
    int port = 0;
    if( !es->zDB()->getMinigameServer( klientId, ip, &port ) )
    {
        ip->release();
        return 0;
    }
    Klient *k = new Klient();
    unsigned char key[ 20 ] = { 88, 103, 192, 232, 69, 54, 57, 3, 239, 138, 234, 172, 126, 72, 81, 55, 205, 97, 59, 255 };
    k->setSendeKey( (char*)key, 20 );
    k->setEmpfangKey( (char*)key, 20 );
    k->verbinde( (unsigned short)port, ip->getText() );
    ip->release();
    char ret = 0;
    k->sendeEncrypted( "\2\2", 2 );
    k->sendeEncrypted( (char*)&klientId, 4 );
    k->getNachrichtEncrypted( &ret, 1 );
    bool erf = ret == 1;
    k->sendeEncrypted( "\3", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    es->addEmpfangen( k->getDownloadBytes( 1 ) );
    es->addGesendet( k->getUploadBytes( 1 ) );
    k->trenne();
    k->release();
    return erf;
}

bool ESGWeiterleitung::spielErstelltAbbrechen( int spielErstelltId )
{
	bool ret = 1;
	Text *ip = new Text( "" );
	int port = 0;
	ret = ret & es->zDB()->getSpielServer( spielErstelltId, ip, &port );
	if( ip->getLength() )
	{
		Klient *klient = new Klient();
		unsigned char key[ 20 ] = { 253, 234, 211, 132, 121, 230, 95, 145, 201, 13, 43, 77, 153, 223, 253, 69, 234, 43, 52, 99 };
		klient->setSendeKey( (char*)key, 20 );
		klient->setEmpfangKey( (char*)key, 20 );
		ret = ret & klient->verbinde( (unsigned short)port, ip->getText() );
		ret = ret & klient->sendeEncrypted( "\x8\x1", 2 );
		char res = 0;
		ret = ret & klient->getNachrichtEncrypted( &res, 1 );
		if( res )
		{
			ret = ret & klient->sendeEncrypted( (char*)&spielErstelltId, 4 );
			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
		}
		ret = (char)ret & res;
		ret = ret & klient->sendeEncrypted( "\x8\x0", 2 );
		ret = ret & klient->getNachrichtEncrypted( &res, 1 );
		ret = (char)ret & res;
		es->addEmpfangen( klient->getDownloadBytes( 1 ) );
		es->addGesendet( klient->getUploadBytes( 1 ) );
		klient->trenne();
		klient = klient->release();
		ip->release();
	}
	return ret;
}

bool ESGWeiterleitung::spielerLeavesGruppe( int gruppeId, int accountId )
{
	bool ret = 1;
	Array< int > *accId = new Array< int >();
	int anzahl = es->zDB()->getSpielerAusGruppe( gruppeId, accId );
	for( int i = 0; i < anzahl; i++ )
	{
		int account = accId->get( i );
		if( account == accountId )
			continue;
		Text *ip = new Text( "" );
		int port = 0;
		ret = ret & es->zDB()->getChatServer( account, ip, &port );
		if( ip->getLength() )
		{
			Klient *klient = new Klient();
			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
			klient->setSendeKey( (char*)key, 20 );
			klient->setEmpfangKey( (char*)key, 20 );
			ret = ret & klient->verbinde( (unsigned short)port, ip->getText() );
			ret = ret & klient->sendeEncrypted( "\5\x15", 2 );
			char res = 0;
			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
			if( res )
			{
				ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
				ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
				ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
			}
			ret = (char)ret & res;
			ret = ret & klient->sendeEncrypted( "\5\x18", 2 );
			res = 0;
			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
			if( res )
			{
				ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
				ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
			}
			ret = (char)ret & res;
			es->addEmpfangen( klient->getDownloadBytes( 1 ) );
			es->addGesendet( klient->getUploadBytes( 1 ) );
			klient->trenne();
			klient = klient->release();
		}
		ip->release();
	}
	accId->release();
	return ret;
}

bool ESGWeiterleitung::setGruppeAdmin( int gruppeId, int adminId )
{
	if( !adminId || !gruppeId )
		return 0;
	bool ret = 1;
	Array< int > *accId = new Array< int >();
	int anzahl = es->zDB()->getSpielerAusGruppe( gruppeId, accId );
	for( int i = 0; i < anzahl; i++ )
	{
		int account = accId->get( i );
		Text *ip = new Text( "" );
		int port = 0;
		ret = ret & es->zDB()->getChatServer( account, ip, &port );
		if( ip->getLength() )
		{
			Klient *klient = new Klient();
			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
			klient->setSendeKey( (char*)key, 20 );
			klient->setEmpfangKey( (char*)key, 20 );
			ret = ret & klient->verbinde( (unsigned short)port, ip->getText() );
			ret = ret & klient->sendeEncrypted( "\5\x1B", 2 );
			char res = 0;
			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
			if( res )
			{
				ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
				ret = ret & klient->sendeEncrypted( (char*)&adminId, 4 );
				ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
			}
			ret = (char)ret & res;
			es->addEmpfangen( klient->getDownloadBytes( 1 ) );
			es->addGesendet( klient->getUploadBytes( 1 ) );
			klient->trenne();
			klient = klient->release();
		}
		ip->release();
	}
	accId->release();
	return ret;
}

bool ESGWeiterleitung::spielerLeavesChatroom( int chatroomId, int accountId )
{
	bool ret = 1;
	Array< int > *accId = new Array< int >();
	int anzahl = es->zDB()->getSpielerAusChatroom( chatroomId, accId );
	for( int i = 0; i < anzahl; i++ )
	{
		int account = accId->get( i );
		if( account == accountId )
			continue;
		Text *ip = new Text( "" );
		int port = 0;
		ret = ret & es->zDB()->getChatServer( account, ip, &port );
		if( ip->getLength() )
		{
			Klient *klient = new Klient();
			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
			klient->setSendeKey( (char*)key, 20 );
			klient->setEmpfangKey( (char*)key, 20 );
			ret = ret & klient->verbinde( (unsigned short)port, ip->getText() );
			ret = ret & klient->sendeEncrypted( "\5\xE", 2 );
			char res = 0;
			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
			if( res )
			{
				ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
				ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
				ret = ret & klient->sendeEncrypted( (char*)&chatroomId, 4 );
				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
			}
			ret = (char)ret & res;
			es->addEmpfangen( klient->getDownloadBytes( 1 ) );
			es->addGesendet( klient->getUploadBytes( 1 ) );
			klient->trenne();
			klient = klient->release();
		}
		ip->release();
	}
	accId->release();
	return ret;
}

bool ESGWeiterleitung::setChatroomAdmin( int chatroomId, int adminId )
{
	if( !adminId || !chatroomId )
		return 0;
	bool ret = 1;
	Text *ip = new Text( "" );
	int port = 0;
	ret = ret & es->zDB()->getChatServer( adminId, ip, &port );
	if( ip->getLength() )
	{
		Klient *klient = new Klient();
		unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
		klient->setSendeKey( (char*)key, 20 );
		klient->setEmpfangKey( (char*)key, 20 );
		ret = ret & klient->verbinde( (unsigned short)port, ip->getText() );
		ret = ret & klient->sendeEncrypted( "\5\x12", 2 );
		char res = 0;
		ret = ret & klient->getNachrichtEncrypted( &res, 1 );
		if( res )
		{
			ret = ret & klient->sendeEncrypted( (char*)&adminId, 4 );
			ret = ret & klient->sendeEncrypted( (char*)&chatroomId, 4 );
			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
		}
		ret = (char)ret & res;
		es->addEmpfangen( klient->getDownloadBytes( 1 ) );
		es->addGesendet( klient->getUploadBytes( 1 ) );
		klient->trenne();
		klient = klient->release();
	}
	ip->release();
	return ret;
}

bool ESGWeiterleitung::kickSpielerAusGruppe( int gruppeId )
{
	if( !gruppeId )
		return 0;
	bool ret = 1;
	Array< int > *accId = new Array< int >();
	int anzahl = es->zDB()->getSpielerAusGruppe( gruppeId, accId );
	for( int i = 0; i < anzahl; i++ )
	{
		int account = accId->get( i );
		Text *ip = new Text( "" );
		int port = 0;
		ret = ret & es->zDB()->getChatServer( account, ip, &port );
		if( ip->getLength() )
		{
			Klient *klient = new Klient();
			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
			klient->setSendeKey( (char*)key, 20 );
			klient->setEmpfangKey( (char*)key, 20 );
			ret = ret & klient->verbinde( (unsigned short)port, ip->getText() );
			ret = ret & klient->sendeEncrypted( "\5\x16", 2 );
			char res = 0;
			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
			if( res )
			{
				ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
				ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
			}
			ret = (char)ret & res;
			es->addEmpfangen( klient->getDownloadBytes( 1 ) );
			es->addGesendet( klient->getUploadBytes( 1 ) );
			klient->trenne();
			klient = klient->release();
		}
		es->zDB()->kickSpielerAusGruppe( gruppeId, account );
		ip->release();
	}
	accId->release();
	return ret;
}

// constant

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

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