Browse Source

Projektdateien hinzufügen.

Kolja Strohm 7 years ago
parent
commit
4fbd2c5151

+ 30 - 0
Anmeldung Server.sln

@@ -0,0 +1,30 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26020.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnmeldungServer", "AnmeldungServer\AnmeldungServer.vcxproj", "{FD37374D-C224-43A9-8D45-BE8AF117E091}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|ARM = Debug|ARM
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|ARM = Release|ARM
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{FD37374D-C224-43A9-8D45-BE8AF117E091}.Debug|ARM.ActiveCfg = Debug|x64
+		{FD37374D-C224-43A9-8D45-BE8AF117E091}.Debug|x64.ActiveCfg = Debug|x64
+		{FD37374D-C224-43A9-8D45-BE8AF117E091}.Debug|x64.Build.0 = Debug|x64
+		{FD37374D-C224-43A9-8D45-BE8AF117E091}.Debug|x86.ActiveCfg = Debug|x64
+		{FD37374D-C224-43A9-8D45-BE8AF117E091}.Release|ARM.ActiveCfg = Release|x64
+		{FD37374D-C224-43A9-8D45-BE8AF117E091}.Release|x64.ActiveCfg = Release|x64
+		{FD37374D-C224-43A9-8D45-BE8AF117E091}.Release|x64.Build.0 = Release|x64
+		{FD37374D-C224-43A9-8D45-BE8AF117E091}.Release|x86.ActiveCfg = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 1788 - 0
AnmeldungServer/AnmeldungServer.cpp

@@ -0,0 +1,1788 @@
+#include "AnmeldungServer.h"
+#include <iostream>
+#include <Klient.h>
+#include <Globals.h>
+
+// Inhalt der AnmeldungServer Klasse aus AnmeldungServer.h
+// Konstruktor 
+AnmeldungServer::AnmeldungServer( InitDatei *zIni )
+	: Thread()
+{
+	Network::Start( 100 );
+	std::cout << "AS: Verbindung mit Datenbank wird hergestellt...\n";
+	db = new ASDatenbank( zIni );
+	klientAnzahl = 0;
+	klients = new RCArray< ASKlient >();
+	empfangen = 0;
+	gesendet = 0;
+	fehler = new Text();
+	ini = zIni->getThis();
+	id = *zIni->zWert( "ServerId" );
+	server = new Server();
+	aServer = new Server();
+	std::cout << "AS: Starten des Admin Servers...\n";
+	if( !aServer->verbinde( (unsigned short)TextZuInt( ini->zWert( "AdminServerPort" )->getText(), 10 ), 10 ) )
+	{
+		std::cout << "AS: Der Admin Server konnte nicht gestartet werden. Das Programm wird beendet.\n";
+		exit( 1 );
+	}
+	db->setServerStatus( id, 2 );
+	end = 0;
+	nichtPausiert = 0;
+	InitializeCriticalSection( &cs );
+	ref = 1;
+	if( zIni->zWert( "Aktiv" )->istGleich( "TRUE" ) )
+	{
+		serverStarten();
+		serverFortsetzen();
+	}
+}
+
+// Destruktor 
+AnmeldungServer::~AnmeldungServer()
+{
+	fehler->release();
+	server->trenne();
+	server->release();
+	aServer->trenne();
+	aServer->release();
+	if( klients )
+		klients->release();
+	ini->release();
+	db->release();
+	DeleteCriticalSection( &cs );
+}
+
+// nicht constant 
+void AnmeldungServer::runn()
+{
+	while( !end )
+	{
+		SKlient *klient;
+		klient = aServer->getKlient();
+		if( end && klient )
+		{
+			klient->trenne();
+			klient = klient->release();
+			Sleep( 1000 );
+			return;
+		}
+		if( !klient )
+			return;
+		ASAKlient *clHandle = new ASAKlient( klient, getThis() );
+		clHandle->start();
+	}
+}
+
+void AnmeldungServer::thread()
+{
+	while( 1 )
+	{
+		SKlient *klient;
+		klient = server->getKlient();
+		if( !klient )
+			break;
+		Framework::getThreadRegister()->cleanUpClosedThreads();
+		ASKlient *clHandle = new ASKlient( klient, getThis() );
+		EnterCriticalSection( &cs );
+		klients->set( clHandle, klientAnzahl );
+		klientAnzahl++;
+		LeaveCriticalSection( &cs );
+		clHandle->start();
+	}
+}
+
+void AnmeldungServer::close()
+{
+	db->setServerStatus( id, 1 );
+	server->trenne();
+#ifdef WIN32
+	warteAufThread( 1000 );
+#endif
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+		klients->z( i )->absturz();
+	klients = klients->release();
+	klientAnzahl = 0;
+	LeaveCriticalSection( &cs );
+	ende();
+	run = 0;
+	end = 1;
+	Klient *klient = new Klient();
+	klient->verbinde( aServer->getPort(), "127.0.0.1" );
+	Sleep( 500 );
+	aServer->trenne();
+	klient->release();
+}
+
+bool AnmeldungServer::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 AnmeldungServer::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 AnmeldungServer::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 AnmeldungServer::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;
+	ende();
+	if( server )
+		server->trenne();
+	return 1;
+}
+
+bool AnmeldungServer::setMaxKlients( int mc )
+{
+	if( !db->setMaxClients( id, mc ) )
+	{
+		fehler->setText( "Die maximale Anzahl der Clients konnte nicht gesetzt werden:\n" );
+		fehler->append( db->getLetzterFehler() );
+		return 0;
+	}
+	return 1;
+}
+
+bool AnmeldungServer::absturzKlient( int klientId )
+{
+	bool gefunden = 0;
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+	{
+		if( klients->z( i )->getKlientNummer() == klientId )
+		{
+			klients->z( i )->absturz();
+			klients->remove( i );
+			klientAnzahl--;
+			gefunden = 1;
+			break;
+		}
+	}
+	LeaveCriticalSection( &cs );
+	return gefunden;
+}
+
+bool AnmeldungServer::removeKlient( ASKlient *zKlient )
+{
+	bool gefunden = 0;
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+	{
+		if( klients->z( i ) == zKlient )
+		{
+			klients->remove( i );
+			klientAnzahl--;
+			gefunden = 1;
+			break;
+		}
+	}
+	LeaveCriticalSection( &cs );
+	return gefunden;
+}
+
+void AnmeldungServer::addGesendet( int bytes )
+{
+	gesendet += bytes;
+}
+
+void AnmeldungServer::addEmpfangen( int bytes )
+{
+	empfangen += bytes;
+}
+
+// constant 
+bool AnmeldungServer::istAn() const
+{
+	return db->serverIstNichtPausiert( id );
+}
+
+Server *AnmeldungServer::zServer() const
+{
+	return server;
+}
+
+ASDatenbank *AnmeldungServer::zDB() const
+{
+	return db;
+}
+
+bool AnmeldungServer::hatClients() const
+{
+	return klientAnzahl > 0;
+}
+
+int AnmeldungServer::getId() const
+{
+	return id;
+}
+
+char *AnmeldungServer::getLetzterFehler() const
+{
+	return fehler->getText();
+}
+
+char *AnmeldungServer::getIp() const
+{
+	return ini->zWert( "ServerIP" )->getText();
+}
+
+// Reference Counting
+AnmeldungServer *AnmeldungServer::getThis()
+{
+	ref++;
+	return this;
+}
+
+AnmeldungServer *AnmeldungServer::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der ASAKlient Klasse aus AnmeldungServer.h
+// Konstruktor 
+ASAKlient::ASAKlient( SKlient *klient, AnmeldungServer *as )
+	: Thread()
+{
+	this->klient = klient;
+	unsigned char key[ 20 ] = { 208, 28, 97, 9, 169, 209, 137, 159, 123, 216, 202, 244, 86, 78, 172, 35, 26, 180, 113, 47 };
+	klient->setSendeKey( (char*)key, 20 );
+	klient->setEmpfangKey( (char*)key, 20 );
+	name = new Text( "" );
+	passwort = new Text( "" );
+	adminId = 0;
+	version = 0;
+	this->as = as;
+}
+
+// Destruktor 
+ASAKlient::~ASAKlient()
+{
+	klient->trenne();
+	klient->release();
+	as->release();
+	name->release();
+	passwort->release();
+}
+
+// nicht constant 
+void ASAKlient::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 = as->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( as->zDB()->adminHatRecht( adminId, Admin_Recht::ASStarten ) )
+					{
+						if( !as->serverStarten() )
+						{
+							Text *err = new Text();
+							err->append( as->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( as->zDB()->adminHatRecht( adminId, Admin_Recht::ASBeenden ) )
+					{
+						if( as->serverBeenden() )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							Text *err = new Text();
+							err->append( as->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( as->isRunning() )
+					{
+						if( as->zDB()->adminHatRecht( adminId, Admin_Recht::ASBeenden ) )
+						{
+							if( as->serverBeenden() )
+								ok = 1;
+							else
+							{
+								Text *err = new Text();
+								err->append( as->getLetzterFehler() );
+								errorZuKlient( err->getText() );
+								err->release();
+							}
+						}
+						else
+							errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+					}
+					else
+						ok = 1;
+					if( ok && as->hatClients() )
+					{
+						errorZuKlient( "Es sind noch Klients Online. Bitte versuche es später erneut." );
+						break;
+					}
+					if( ok )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						std::cout << "AS: Der Server wird von Benutzer " << adminId << " heruntergefahren.\n";
+						as->close();
+						br = 1;
+					}
+				}
+				break;
+			case 7: // Progtamm abstürzen
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					bool ok = 0;
+					if( as->isRunning() )
+					{
+						if( as->zDB()->adminHatRecht( adminId, Admin_Recht::ASBeenden ) )
+						{
+							as->serverBeenden();
+							ok = 1;
+						}
+						else
+							errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+					}
+					else
+						ok = 1;
+					if( ok )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						std::cout << "AS: Der Server wurde von Benutzer " << adminId << " terminiert.\n";
+						as->close();
+						br = 1;
+					}
+				}
+				break;
+			case 8: // Status Frage
+				if( 1 )
+				{
+					char status = 0;
+					if( as->isRunning() )
+					{
+						status = 1;
+						if( as->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( as->zDB()->adminHatRecht( adminId, Admin_Recht::ASPausieren ) )
+					{
+						bool ok = 0;
+						if( pause )
+							ok = as->serverPause();
+						else
+							ok = as->serverFortsetzen();
+						if( ok )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							Text *err = new Text();
+							err->append( as->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( as->zDB()->adminHatRecht( adminId, Admin_Recht::ASMCChange ) )
+					{
+						if( as->setMaxKlients( maxC ) )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							Text *err = new Text();
+							err->append( as->getLetzterFehler() );
+							errorZuKlient( err->getText() );
+							err->release();
+						}
+					}
+					else
+						errorZuKlient( "Du bist nicht berechtigt die maximale Anzahl der Clients zu verändern." );
+				}
+				break;
+            case 0xC: // klient absturtz
+                if( 1 )
+                {
+                    klient->sendeEncrypted( "\1", 1 );
+                    int klientId = 0;
+                    klient->getNachrichtEncrypted( (char*)&klientId, 4 );
+                    if( klientId && as->absturzKlient( klientId ) )
+                        klient->sendeEncrypted( "\1", 1 );
+                    else
+                        klient->sendeEncrypted( "\0", 1 );
+                }
+                break;
+			default:
+				errorZuKlient( "Unbekannte Nachricht!" );
+				break;
+			}
+			if( br )
+				break;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+		}
+	}
+	as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	as->addGesendet( klient->getUploadBytes( 1 ) );
+	delete this;
+}
+
+void ASAKlient::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 ASKlient aus AnmeldungServer.h
+// Konstruktor
+ASKlient::ASKlient( SKlient *klient, AnmeldungServer *as )
+	: Thread()
+{
+	this->klient = 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 };
+	klient->setSendeKey( (char*)key, 20 );
+	klient->setEmpfangKey( (char*)key, 20 );
+	klientNummer = 0;
+	this->as = as;
+	accountId = 0;
+	ref = 1;
+}
+
+// Destruktor 
+ASKlient::~ASKlient()
+{
+	klient->release();
+	as->release();
+}
+
+// nicht constant 
+void ASKlient::absturz()
+{
+	ende();
+	klient->trenne();
+	as->zDB()->unregisterKlient( klientNummer, as->getId() );
+}
+
+void ASKlient::thread()
+{
+	while( 1 )
+	{
+		char c = 0;
+		if( !klient->getNachrichtEncrypted( &c, 1 ) )
+			break;
+		else
+		{
+			bool br = 0;
+			switch( c )
+			{
+			case 1: // Klient identifikation
+				klient->getNachrichtEncrypted( (char*)&klientNummer, 4 );
+				if( !as->zDB()->proveKlient( klientNummer, as->getId() ) )
+				{
+					klientNummer = 0;
+					errorZuKlient( "Du bist nicht für diesen Server eingetragen" );
+				}
+				else
+				{
+					accountId = as->zDB()->getAccountId( klientNummer );
+					if( accountId )
+					{
+						Text *key = as->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
+					{
+						klientNummer = 0;
+						errorZuKlient( "Du bist nicht eingeloggt." );
+					}
+				}
+				break;
+			case 2: // Main / Erhaltung Server message
+				if( 1 )
+				{
+					char befehl = 0;
+					klient->getNachrichtEncrypted( &befehl, 1 );
+					switch( befehl )
+					{
+					case 2: // klient absturtz
+						if( 1 )
+						{
+							int klientId = 0;
+							klient->getNachrichtEncrypted( (char*)&klientId, 4 );
+							if( klientId && as->absturzKlient( klientId ) )
+								klient->sendeEncrypted( "\1", 1 );
+							else
+								klient->sendeEncrypted( "\0", 1 );
+						}
+						break;
+					default:
+						errorZuKlient( "Befehl nicht bekannt!" );
+						break;
+					}
+				}
+				break;
+			case 3: // Verbindungsende
+				br = 1;
+				klient->sendeEncrypted( "\1", 1 );
+				break;
+			case 4: // unregister Klient
+				if( !klientNummer )
+				{
+					errorZuKlient( "Du bist nicht Identifiziert." );
+					break;
+				}
+				as->zDB()->unregisterKlient( klientNummer, as->getId() );
+				klient->sendeEncrypted( "\1", 1 );
+				break;
+			case 5: // gruppe erstellen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int karteId = 0;
+					klient->getNachrichtEncrypted( (char*)&karteId, 4 );
+					int gruppeId = 0;
+					int ret = as->zDB()->gruppeErstellen( accountId, karteId, &gruppeId );
+					switch( ret )
+					{
+					case 0:
+						errorZuKlient( "Du bist nicht eingeloggt." );
+						break;
+					case 1:
+						errorZuKlient( "Du wurdest bereits einem Spiel zugeordnet." );
+						break;
+					case 2:
+						errorZuKlient( "Du bist in einem anderen noch laufendem Spiel. Spiele es zu Ende." );
+						break;
+					case 3:
+						errorZuKlient( "Du bist in einer anderen Gruppe." );
+						break;
+					case 4:
+						errorZuKlient( "Du bist bereits in der Warteschlange." );
+						break;
+					case 5:
+						errorZuKlient( "Die Karte ist zur Zeit nicht spielbar." );
+						break;
+					case 6:
+						errorZuKlient( "Unbekannter Fehler." );
+						break;
+					case 7:
+						klient->sendeEncrypted( "\1", 1 );
+						klient->sendeEncrypted( (char*)&gruppeId, 4 );
+						break;
+					}
+				}
+				break;
+			case 6: // gruppe betreten
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int gruppeId = 0;
+					klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+					if( as->zDB()->gruppeIstInWarteschlange( gruppeId ) )
+					{
+						errorZuKlient( "Die Gruppe befindet sich bereits in der Warteschlange." );
+						break;
+					}
+					if( !as->zDB()->gruppeSpielerIstEingeladen( gruppeId, accountId ) )
+					{
+						errorZuKlient( "Du bist nicht mehr eingeladen." );
+						break;
+					}
+					int anzahl = 0;
+					Array< int > *accIds = new Array< int >();
+					as->zDB()->getSpielerInGruppe( gruppeId, accIds, &anzahl );
+					int res = as->zDB()->gruppeBetreten( accountId, gruppeId );
+					switch( res )
+					{
+					case 0:
+						errorZuKlient( "Du bist nicht eingeloggt." );
+						break;
+					case 1:
+						errorZuKlient( "Du wurdest bereits einem Spiel zugeordnet." );
+						break;
+					case 2:
+						errorZuKlient( "Du bist in einem anderen noch laufendem Spiel. Spiele es zu Ende." );
+						break;
+					case 3:
+						errorZuKlient( "Du bist in einer anderen Gruppe." );
+						break;
+					case 4:
+						errorZuKlient( "Du bist bereits in der Warteschlange." );
+						break;
+					case 5:
+						errorZuKlient( "Die Gruppe ist bereits in einem Spiel." );
+						break;
+					case 6:
+						errorZuKlient( "Unbekannter Fehler." );
+						break;
+					case 7:
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							klient->sendeEncrypted( (char*)&anzahl, 4 );
+							for( int i = 0; i < anzahl; i++ )
+							{
+								int id = accIds->get( i );
+								if( id == accountId )
+									continue;
+								klient->sendeEncrypted( (char*)&id, 4 );
+							}
+							as->zDB()->gruppeEinladungAbbrechen( as->zDB()->getGruppeAdminId( gruppeId ), gruppeId, accountId );
+							MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+							weiter->spielerBetrittGruppe( gruppeId );
+							weiter->release();
+						}
+						break;
+					}
+					accIds->release();
+				}
+				break;
+			case 7: // gruppe verlassen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int gruppeId = 0;
+					klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+					if( as->zDB()->gruppeIstInWarteschlange( gruppeId ) )
+					{
+						errorZuKlient( "Die Gruppe befindet sich bereits in der Warteschlange." );
+						break;
+					}
+					int ret = as->zDB()->gruppeVerlassen( accountId, gruppeId );
+					if( !ret )
+						errorZuKlient( "Du kannst die gruppe momentan nicht mehr verlassen." );
+					if( ret == 1 )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+						weiter->spielerLeavesGruppe( gruppeId );
+						weiter->release();
+					}
+					if( ret == 2 )
+						klient->sendeEncrypted( "\1", 1 );
+					if( ret == 3 )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						int adminId = as->zDB()->getGruppeAdminId( gruppeId );
+						MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+						weiter->setGruppeAdmin( gruppeId, adminId );
+						weiter->spielerLeavesGruppe( gruppeId );
+						weiter->release();
+					}
+					if( ret == 4 )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						Array< int > *spieler = new Array< int >();
+						int anzahl = 0;
+						MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+						if( as->zDB()->getSpielerInGruppe( gruppeId, spieler, &anzahl ) )
+						{
+							for( int i = 0; i < anzahl; i++ )
+							{
+								if( spieler->hat( i ) )
+								{
+									weiter->kickSpielerAusGruppe( spieler->get( i ), gruppeId );
+									as->zDB()->gruppeVerlassen( spieler->get( i ), gruppeId );
+								}
+							}
+						}
+						spieler->release();
+						weiter->release();
+					}
+				}
+				break;
+			case 9: // gruppe anmelden
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int gruppeId = 0;
+					klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+					if( !as->zDB()->spielerBesitztKarte( accountId, as->zDB()->getGruppenKarte( gruppeId ) ) )
+					{
+						errorZuKlient( "Du besitzt entweder die Karte oder das Spiel nicht." );
+						break;
+					}
+					if( as->zDB()->getGruppeSpielStarten( gruppeId ) && as->zDB()->getSpielerInGruppeAnzahl( gruppeId ) <= 1 )
+					{
+						errorZuKlient( "Es müssen mindestens 2 Spieler in der Gruppe vorhanden sein." );
+						break;
+					}
+					if( as->zDB()->gruppeAnmelden( accountId, gruppeId ) )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+						weiter->gruppeAngemeldet( gruppeId );
+						weiter->release();
+					}
+					else
+						errorZuKlient( "Du kannst die Gruppe nicht anmelden." );
+				}
+				break;
+			case 0xA: // gruppe abmelden
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int gruppeId = 0;
+					klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+					if( as->zDB()->gruppeAbmelden( accountId, gruppeId ) )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+						weiter->gruppeAbgemeldet( gruppeId );
+						weiter->release();
+					}
+					else
+						errorZuKlient( "Du kannst die Gruppe nicht abmelden." );
+					break;
+				}
+			case 0xB: // spieler einladen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int gruppeId = 0;
+					int zuAccountId = 0;
+					klient->getNachrichtEncrypted( (char*)&zuAccountId, 4 );
+					klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+					if( as->zDB()->gruppeIstInWarteschlange( gruppeId ) )
+					{
+						errorZuKlient( "Die Gruppe befindet sich bereits in der Warteschlange." );
+						break;
+					}
+					if( as->zDB()->gruppeSpielerEinladen( accountId, zuAccountId, gruppeId ) )
+					{
+						MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+						if( weiter->spielEinladung( gruppeId, zuAccountId ) )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							if( weiter->zLetzterFehler()->getLength() )
+								errorZuKlient( weiter->zLetzterFehler()->getText() );
+							else
+								errorZuKlient( "Fehler beim zuteilen der Einladung." );
+						}
+						weiter->release();
+					}
+					else
+						errorZuKlient( "Du kannst diesen Spieler nicht einladen." );
+				}
+				break;
+			case 0xC: // spieler kicken
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int gruppeId = 0;
+					int zuAccountId = 0;
+					klient->getNachrichtEncrypted( (char*)&zuAccountId, 4 );
+					klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+					if( as->zDB()->gruppeIstInWarteschlange( gruppeId ) )
+					{
+						errorZuKlient( "Die Gruppe befindet sich bereits in der Warteschlange." );
+						break;
+					}
+					if( as->zDB()->spielerKannKicken( accountId, gruppeId ) )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						as->zDB()->gruppeVerlassen( zuAccountId, gruppeId );
+						MsgWeiterleitung *weiter = new MsgWeiterleitung( zuAccountId, as->getThis() );
+						weiter->kickSpielerAusGruppe( zuAccountId, gruppeId );
+						weiter->spielerLeavesGruppe( gruppeId );
+						weiter->release();
+					}
+					else
+						errorZuKlient( "Du hast keine berechtigung diesen Spieler zu kicken." );
+				}
+				break;
+			case 0xD: // gruppen Nachricht senden
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int gruppeId = 0;
+					char key = 0;
+					klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+					klient->getNachrichtEncrypted( &key, 1 );
+					char *nachricht = new char[ key + 1 ];
+					nachricht[ (int)key ] = 0;
+					if( key )
+						klient->getNachrichtEncrypted( nachricht, key );
+					else
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						delete[] nachricht;
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					Text *message = as->zDB()->getAccountRufName( accountId );
+					message->append( ": " );
+					message->append( nachricht );
+					delete[] nachricht;
+					MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+					weiter->gruppenNachricht( gruppeId, message->getText() );
+					weiter->release();
+					message->release();
+				}
+				break;
+			case 0xE: // spieler anmelden
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int karteId = 0;
+					klient->getNachrichtEncrypted( (char*)&karteId, 4 );
+					if( !as->zDB()->spielerBesitztKarte( accountId, karteId ) )
+					{
+						errorZuKlient( "Du besitzt entweder die Karte oder das Spiel nicht." );
+						break;
+					}
+					int ret = as->zDB()->accountAnmelden( accountId, karteId );
+					switch( ret )
+					{
+					case 0:
+						errorZuKlient( "Du bist nicht eingeloggt." );
+						break;
+					case 1:
+						errorZuKlient( "Du wurdest bereits einem Spiel zugeordnet." );
+						break;
+					case 2:
+						errorZuKlient( "Du bist in einem anderen noch laufendem Spiel. Spiele es zu Ende." );
+						break;
+					case 3:
+						errorZuKlient( "Du bist in einer anderen Gruppe." );
+						break;
+					case 4:
+						errorZuKlient( "Du bist bereits in der Warteschlange." );
+						break;
+					case 5:
+						errorZuKlient( "Die Karte ist zur Zeit nicht spielbar." );
+						break;
+					case 6:
+						errorZuKlient( "Unbekannter Fehler." );
+						break;
+					case 7:
+						klient->sendeEncrypted( "\1", 1 );
+						break;
+					}
+				}
+				break;
+			case 0xF: // spieler abmelden
+				if( !klientNummer )
+				{
+					errorZuKlient( "Du bist nicht Identifiziert." );
+					break;
+				}
+				klient->sendeEncrypted( "\1", 1 );
+				as->zDB()->accountAbmelden( accountId );
+				break;
+			case 0x10: // gruppe Spiel Starten
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					char spielStarten = 0;
+					int gruppeId = 0;
+					klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+					klient->getNachrichtEncrypted( &spielStarten, 1 );
+					if( spielStarten && as->zDB()->getSpielerInGruppeAnzahl( gruppeId ) < 2 )
+					{
+						errorZuKlient( "Es müssen sich mindestens 2 Spieler in der Gruppe befinden." );
+						break;
+					}
+					if( as->zDB()->setGruppeSpielStarten( accountId, gruppeId, spielStarten == 1 ) )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+						weiter->gruppeSpielStarten( gruppeId, spielStarten == 1 );
+						weiter->release();
+					}
+					else
+						errorZuKlient( "Du kannst diese Option nicht setzen." );
+				}
+				break;
+			case 0x11: // gruppe Einladung abbrechen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int gruppeId = 0;
+					int accountId = 0;
+					klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+					klient->getNachrichtEncrypted( (char*)&accountId, 4 );
+					if( as->zDB()->gruppeEinladungAbbrechen( this->accountId, gruppeId, accountId ) )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+						weiter->spielEinladungAbbrechen( gruppeId, accountId );
+						weiter->release();
+					}
+					else
+						errorZuKlient( "Du kannst diese Option nicht setzen." );
+				}
+				break;
+			case 0x12: // gruppe Einladung ablehnen
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int gruppeId = 0;
+					klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+					klient->sendeEncrypted( "\1", 1 );
+					as->zDB()->gruppeEinladungAbbrechen( as->zDB()->getGruppeAdminId( gruppeId ), gruppeId, accountId );
+					MsgWeiterleitung *weiter = new MsgWeiterleitung( accountId, as->getThis() );
+					weiter->spielEinladungAblehnen( gruppeId );
+					weiter->release();
+				}
+				break;
+			case 0x13: // ping
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+				}
+				break;
+			default:
+				errorZuKlient( "Unbekannte Nachricht!" );
+				break;
+			}
+			if( br )
+				break;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+		}
+	}
+	as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	as->addGesendet( klient->getUploadBytes( 1 ) );
+	as->removeKlient( this ); // delete this
+}
+
+// constant
+void ASKlient::errorZuKlient( const char *nachricht ) const // sendet eine Fehlernachricht zum Klient
+{
+	klient->sendeEncrypted( "\3", 1 );
+	char key = (char)textLength( nachricht );
+	klient->sendeEncrypted( &key, 1 );
+	klient->sendeEncrypted( nachricht, key );
+}
+
+int ASKlient::getKlientNummer() const // gibt die KlientId zurück
+{
+	return klientNummer;
+}
+
+// Reference Counting
+ASKlient *ASKlient::getThis()
+{
+	ref++;
+	return this;
+}
+
+ASKlient *ASKlient::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der MsgWeiterleitung Klasse aus AnmeldungServer.h
+// Konstruktor
+MsgWeiterleitung::MsgWeiterleitung( int accountId, AnmeldungServer *as )
+{
+	fehler = new Text( "" );
+	this->accountId = accountId;
+	this->as = as;
+	ref = 1;
+}
+
+// Destruktor
+MsgWeiterleitung::~MsgWeiterleitung()
+{
+	fehler->release();
+	as->release();
+}
+
+// nicht constant
+bool MsgWeiterleitung::spielerBetrittGruppe( int gruppeId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = 0;
+	as->zDB()->getSpielerInGruppe( gruppeId, accId, &anzahl );
+	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 & as->zDB()->getChatServer( account, ip, &port );
+		if( ip->istGleich( as->getIp() ) )
+			ip->setText( "127.0.0.1" );
+		if( ip->getLength() )
+		{
+			Klient *klient = new Klient();
+			unsigned char key[ 20 ] = { 79, 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\x14", 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;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MsgWeiterleitung::spielerLeavesGruppe( int gruppeId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = 0;
+	as->zDB()->getSpielerInGruppe( gruppeId, accId, &anzahl );
+	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 & as->zDB()->getChatServer( account, ip, &port );
+		if( ip->istGleich( as->getIp() ) )
+			ip->setText( "127.0.0.1" );
+		if( ip->getLength() )
+		{
+			Klient *klient = new Klient();
+			unsigned char key[ 20 ] = { 79, 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;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MsgWeiterleitung::setGruppeAdmin( int gruppeId, int admin )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = 0;
+	as->zDB()->getSpielerInGruppe( gruppeId, accId, &anzahl );
+	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 & as->zDB()->getChatServer( account, ip, &port );
+		if( ip->istGleich( as->getIp() ) )
+			ip->setText( "127.0.0.1" );
+		if( ip->getLength() )
+		{
+			Klient *klient = new Klient();
+			unsigned char key[ 20 ] = { 79, 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*)&admin, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MsgWeiterleitung::kickSpielerAusGruppe( int accountId, int gruppeId )
+{
+	bool ret = 1;
+	Text *ip = new Text( "" );
+	int port = 0;
+	ret = ret & as->zDB()->getChatServer( accountId, ip, &port );
+	if( ip->istGleich( as->getIp() ) )
+		ip->setText( "127.0.0.1" );
+	if( ip->getLength() )
+	{
+		Klient *klient = new Klient();
+		unsigned char key[ 20 ] = { 79, 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*)&accountId, 4 );
+			ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+		}
+		ret = (char)ret & res;
+		as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+		as->addGesendet( klient->getUploadBytes( 1 ) );
+		klient->trenne();
+		klient = klient->release();
+	}
+	ip->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MsgWeiterleitung::gruppenNachricht( int gruppeId, char *txt )
+{
+	bool ret = 1;
+	char len = (char)textLength( txt );
+	if( !len )
+		return 0;
+	Array< int > *accId = new Array< int >();
+	int anzahl = 0;
+	as->zDB()->getSpielerInGruppe( gruppeId, accId, &anzahl );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		Text *ip = new Text( "" );
+		int port = 0;
+		ret = ret & as->zDB()->getChatServer( account, ip, &port );
+		if( ip->istGleich( as->getIp() ) )
+			ip->setText( "127.0.0.1" );
+		if( ip->getLength() )
+		{
+			Klient *klient = new Klient();
+			unsigned char key[ 20 ] = { 79, 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\x19", 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->sendeEncrypted( (char*)&len, 1 );
+				if( len )
+					ret = ret & klient->sendeEncrypted( txt, len );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MsgWeiterleitung::gruppeAngemeldet( int gruppeId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = 0;
+	as->zDB()->getSpielerInGruppe( gruppeId, accId, &anzahl );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		Text *ip = new Text( "" );
+		int port = 0;
+		ret = ret & as->zDB()->getChatServer( account, ip, &port );
+		if( ip->istGleich( as->getIp() ) )
+			ip->setText( "127.0.0.1" );
+		if( ip->getLength() )
+		{
+			Klient *klient = new Klient();
+			unsigned char key[ 20 ] = { 79, 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\x17", 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;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MsgWeiterleitung::gruppeAbgemeldet( int gruppeId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = 0;
+	as->zDB()->getSpielerInGruppe( gruppeId, accId, &anzahl );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		Text *ip = new Text( "" );
+		int port = 0;
+		ret = ret & as->zDB()->getChatServer( account, ip, &port );
+		if( ip->istGleich( as->getIp() ) )
+			ip->setText( "127.0.0.1" );
+		if( ip->getLength() )
+		{
+			Klient *klient = new Klient();
+			unsigned char key[ 20 ] = { 79, 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\x18", 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;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MsgWeiterleitung::gruppeSpielStarten( int gruppeId, bool starten )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = 0;
+	as->zDB()->getSpielerInGruppe( gruppeId, accId, &anzahl );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		Text *ip = new Text( "" );
+		int port = 0;
+		ret = ret & as->zDB()->getChatServer( account, ip, &port );
+		if( ip->istGleich( as->getIp() ) )
+			ip->setText( "127.0.0.1" );
+		if( ip->getLength() )
+		{
+			Klient *klient = new Klient();
+			unsigned char key[ 20 ] = { 79, 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\x1A", 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->sendeEncrypted( (char*)&starten, 1 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MsgWeiterleitung::spielEinladung( int gruppeId, int accountId )
+{
+	// Einladung zum spieler Senden
+	bool ret = 1;
+	Text *ip = new Text( "" );
+	int port = 0;
+	ret = ret & as->zDB()->getChatServer( accountId, ip, &port );
+	if( ip->istGleich( as->getIp() ) )
+		ip->setText( "127.0.0.1" );
+	if( ip->getLength() )
+	{
+		Klient *klient = new Klient();
+		unsigned char key[ 20 ] = { 79, 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\5", 2 );
+		char res = 0;
+		ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+		if( res )
+		{
+			ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
+			ret = ret & klient->sendeEncrypted( (char*)&this->accountId, 4 );
+			ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+		}
+		ret = (char)ret & res;
+		as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+		as->addGesendet( klient->getUploadBytes( 1 ) );
+		klient->trenne();
+		klient = klient->release();
+	}
+	ip->release();
+	// Einladung zu den Gruppenmitgliedern senden
+	Array< int > *accId = new Array< int >();
+	int anzahl = 0;
+	as->zDB()->getSpielerInGruppe( gruppeId, accId, &anzahl );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		Text *ip = new Text( "" );
+		int port = 0;
+		ret = ret & as->zDB()->getChatServer( account, ip, &port );
+		if( ip->istGleich( as->getIp() ) )
+			ip->setText( "127.0.0.1" );
+		if( ip->getLength() )
+		{
+			Klient *klient = new Klient();
+			unsigned char key[ 20 ] = { 79, 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\x1F", 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->sendeEncrypted( (char*)&accountId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MsgWeiterleitung::spielEinladungAbbrechen( int gruppeId, int accountId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = 0;
+	as->zDB()->getSpielerInGruppe( gruppeId, accId, &anzahl );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		Text *ip = new Text( "" );
+		int port = 0;
+		ret = ret & as->zDB()->getChatServer( account, ip, &port );
+		if( ip->istGleich( as->getIp() ) )
+			ip->setText( "127.0.0.1" );
+		if( ip->getLength() )
+		{
+			Klient *klient = new Klient();
+			unsigned char key[ 20 ] = { 79, 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\x1E", 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->sendeEncrypted( (char*)&accountId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MsgWeiterleitung::spielEinladungAblehnen( int gruppeId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = 0;
+	as->zDB()->getSpielerInGruppe( gruppeId, accId, &anzahl );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		Text *ip = new Text( "" );
+		int port = 0;
+		ret = ret & as->zDB()->getChatServer( account, ip, &port );
+		if( ip->istGleich( as->getIp() ) )
+			ip->setText( "127.0.0.1" );
+		if( ip->getLength() )
+		{
+			Klient *klient = new Klient();
+			unsigned char key[ 20 ] = { 79, 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\x1C", 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;
+			as->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			as->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	if( !ret )
+		fehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+// constant
+int MsgWeiterleitung::getAccountId() const
+{
+	return accountId;
+}
+
+Text *MsgWeiterleitung::getLetzterFehler() const
+{
+	return fehler->getThis();
+}
+
+Text *MsgWeiterleitung::zLetzterFehler() const
+{
+	return fehler;
+}
+
+// Reference Counting
+MsgWeiterleitung *MsgWeiterleitung::getThis()
+{
+	ref++;
+	return this;
+}
+
+MsgWeiterleitung *MsgWeiterleitung::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 144 - 0
AnmeldungServer/AnmeldungServer.h

@@ -0,0 +1,144 @@
+#ifndef AnmeldungServer_H
+#define AnmeldungServer_H
+
+#include <Server.h>
+#include <Thread.h>
+#include <Datei.h>
+#include <Text.h>
+#include <InitDatei.h>
+#include "Datenbank.h"
+
+using namespace Framework;
+using namespace Network;
+
+class ASKlient;
+
+class AnmeldungServer : public Thread
+{
+private:
+	Server *server;
+	Server *aServer;
+	InitDatei *ini;
+	ASDatenbank *db;
+	CRITICAL_SECTION cs;
+	RCArray< ASKlient > *klients;
+	Text *fehler;
+	int klientAnzahl;
+	int id;
+	bool nichtPausiert;
+	int empfangen;
+	int gesendet;
+	bool end;
+	int ref;
+
+public:
+	// Konstruktor 
+	AnmeldungServer( InitDatei *zIni );
+	// Destruktor 
+	virtual ~AnmeldungServer();
+	// nicht constant 
+	void runn();
+	void thread();
+	void close();
+	bool serverStarten();
+	bool serverPause();
+	bool serverFortsetzen();
+	bool serverBeenden();
+	bool setMaxKlients( int mc );
+	bool absturzKlient( int klientId );
+	bool removeKlient( ASKlient *zKlient );
+	void addGesendet( int bytes );
+	void addEmpfangen( int bytes );
+	// conatant 
+	bool istAn() const;
+	Server *zServer() const;
+	ASDatenbank *zDB() const;
+	bool hatClients() const;
+	int getId() const;
+	char *getLetzterFehler() const;
+	char *getIp() const;
+	// Reference Counting
+	AnmeldungServer *getThis();
+	AnmeldungServer *release();
+};
+
+class ASAKlient : public Thread
+{
+private:
+	SKlient *klient;
+	Text *name;
+	Text *passwort;
+	int adminId;
+	AnmeldungServer *as;
+	int version;
+
+public:
+	// Konstruktor 
+	ASAKlient( SKlient *klient, AnmeldungServer *as );
+	// Destruktor 
+	virtual ~ASAKlient();
+	// nicht constant
+	void thread();
+	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum AKlient
+};
+
+class ASKlient : public Thread
+{
+private:
+	SKlient     *klient;
+	unsigned int klientNummer;
+	AnmeldungServer *as;
+	int accountId;
+	int ref;
+
+public:
+	// Konstruktor 
+	ASKlient( SKlient *klient, AnmeldungServer *as );
+	// Destruktor 
+	virtual ~ASKlient();
+	// nicht constant
+	void absturz();
+	virtual void thread();
+	// constant
+	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum Klient
+	int getKlientNummer() const;
+	// Reference Counting
+	ASKlient *getThis();
+	ASKlient *release();
+};
+
+class MsgWeiterleitung
+{
+private:
+	AnmeldungServer *as;
+	int accountId;
+	int ref;
+	Text *fehler;
+
+public:
+	// Konstruktor
+	MsgWeiterleitung( int accountId, AnmeldungServer *as );
+	// Destruktor
+	virtual ~MsgWeiterleitung();
+	// nicht constant
+	bool spielerBetrittGruppe( int gruppeId );
+	bool spielerLeavesGruppe( int gruppeId );
+	bool setGruppeAdmin( int gruppeId, int admin );
+	bool kickSpielerAusGruppe( int accountId, int gruppeId );
+	bool gruppenNachricht( int gruppeId, char *txt );
+	bool gruppeAngemeldet( int gruppeId );
+	bool gruppeAbgemeldet( int gruppeId );
+	bool gruppeSpielStarten( int gruppeId, bool starten );
+	bool spielEinladung( int gruppeId, int accountId );
+	bool spielEinladungAbbrechen( int gruppeId, int accountId );
+	bool spielEinladungAblehnen( int gruppeId );
+	// constant
+	int getAccountId() const;
+	Text *getLetzterFehler() const;
+	Text *zLetzterFehler() const;
+	// Reference Counting
+	MsgWeiterleitung *getThis();
+	MsgWeiterleitung *release();
+};
+
+#endif

+ 76 - 0
AnmeldungServer/AnmeldungServer.vcxproj

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{fd37374d-c224-43a9-8d45-be8af117e091}</ProjectGuid>
+    <Keyword>Linux</Keyword>
+    <RootNamespace>AnmeldungServer</RootNamespace>
+    <MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
+    <ApplicationType>Linux</ApplicationType>
+    <ApplicationTypeRevision>1.0</ApplicationTypeRevision>
+    <TargetLinuxPlatform>Generic</TargetLinuxPlatform>
+    <LinuxProjectType>{D51BCBC9-82E9-4017-911E-C93873C4EA2B}</LinuxProjectType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <RemoteRootDir>/home/kolja/projects</RemoteRootDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <RemoteRootDir>/home/kolja/projects</RemoteRootDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Label="Shared" />
+  <ImportGroup Label="PropertySheets" />
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/release</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;..\..\..\..\Allgemein\Network\Network;..\..\..\..\Allgemein\sql\sql;../../../Framework/release;../../../Network/release;../../../sql/release;$(IncludePath)</IncludePath>
+    <TargetExt />
+    <OutDir>$(ProjectDir)bin\$(Platform)\release\</OutDir>
+    <IntDir>$(ProjectDir)obj\$(Platform)\release\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/debug</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;..\..\..\..\Allgemein\Network\Network;..\..\..\..\Allgemein\sql\sql;../../../Framework/debug;../../../Network/debug;../../../sql/debug;$(IncludePath)</IncludePath>
+    <TargetExt />
+    <OutDir>$(ProjectDir)bin\$(Platform)\debug\</OutDir>
+    <IntDir>$(ProjectDir)obj\$(Platform)\debug\</IntDir>
+  </PropertyGroup>
+  <ItemGroup>
+    <ClCompile Include="AnmeldungServer.cpp" />
+    <ClCompile Include="Datenbank.cpp" />
+    <ClCompile Include="main.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="AnmeldungServer.h" />
+    <ClInclude Include="Datenbank.h" />
+  </ItemGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Link>
+      <LibraryDependencies>Framework;Network;SQL;pq;pthread</LibraryDependencies>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/release/bin/x64/release;$(RemoteRootDir)/Network/release/bin/x64/release;$(RemoteRootDir)/Framework/release/bin/x64/release;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Link>
+      <LibraryDependencies>dbgFramework;dbgNetwork;dbgSQL;pq;pthread</LibraryDependencies>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/debug/bin/x64/debug;$(RemoteRootDir)/Network/debug/bin/x64/debug;$(RemoteRootDir)/Framework/debug/bin/x64/debug;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>

+ 30 - 0
AnmeldungServer/AnmeldungServer.vcxproj.filters

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Headerdateien">
+      <UniqueIdentifier>{8072c10b-b0e0-47cb-b2ca-23223666c536}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{d408292d-0209-45fd-b80f-6a4829586f19}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Datenbank.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="AnmeldungServer.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="main.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="AnmeldungServer.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Datenbank.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>

+ 750 - 0
AnmeldungServer/Datenbank.cpp

@@ -0,0 +1,750 @@
+#include "Datenbank.h"
+#include <iostream>
+
+// Inhalt der ASDatenbank Klasse aus Datenbank.h
+// Konstruktor
+ASDatenbank::ASDatenbank( InitDatei *zIni )
+{
+    datenbank = new Datenbank( zIni->zWert( "DBBenutzer" )->getText(), zIni->zWert( "DBPasswort" )->getText(),
+        zIni->zWert( "DBName" )->getText(), zIni->zWert( "DBIP" )->getText(),
+        (unsigned short)TextZuInt( zIni->zWert( "DBPort" )->getText(), 10 ) );
+    if( !datenbank->istOk() )
+    {
+        std::cout << "AS: Die Verbindung zur Datenbank konnte nicht hergestellt werden.\nDas Programm wird beendet.";
+        exit( 1 );
+    }
+    InitializeCriticalSection( &cs );
+    ref = 1;
+    Text befehl = "SELECT port, admin_port  FROM server WHERE id = ";
+    befehl += zIni->zWert( "ServerId" )->getText();
+    lock();
+    datenbank->befehl( befehl );
+    Result res = datenbank->getResult();
+    unlock();
+    if( res.zeilenAnzahl == 1 )
+    {
+        zIni->addWert( "ServerPort", res.values[ 0 ] );
+        zIni->addWert( "AdminServerPort", res.values[ 1 ] );
+    }
+    res.destroy();
+}
+
+// Destruktor
+ASDatenbank::~ASDatenbank()
+{
+    datenbank->release();
+    DeleteCriticalSection( &cs );
+}
+
+// nicht constant
+void ASDatenbank::lock()
+{
+    EnterCriticalSection( &cs );
+}
+
+void ASDatenbank::unlock()
+{
+    LeaveCriticalSection( &cs );
+}
+
+int ASDatenbank::istAdministrator( const char *name, const char *passwort )
+{
+    Text *befehl = new Text( "SELECT id FROM benutzer WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char*)n );
+    befehl->append( "' AND passwort = md5( '" );
+    Text p( passwort );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char*)p );
+    befehl->append( "' )" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    int ret = 0;
+    if( res.zeilenAnzahl > 0 )
+        ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+bool ASDatenbank::adminHatRecht( int id, int recht )
+{
+    Text *befehl = new Text( "SELECT * FROM benutzer_rechte WHERE benutzer_id = " );
+    befehl->append( id );
+    befehl->append( " AND rechte_id = " );
+    befehl->append( recht );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    int ret = datenbank->getZeilenAnzahl();
+    unlock();
+    befehl->release();
+    return ret != 0;
+}
+
+bool ASDatenbank::proveKlient( int num, int sNum )
+{
+    Text *befehl = new Text( "SELECT * FROM server_client WHERE server_id = " );
+    befehl->append( sNum );
+    befehl->append( " AND client_id = " );
+    befehl->append( num );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    bool ret = 0;
+    if( res.zeilenAnzahl == 1 )
+        ret = 1;
+    res.destroy();
+    return ret;
+}
+
+Text *ASDatenbank::getKlientKey( int cId )
+{
+    lock();
+    if( !datenbank->befehl( Text( "SELECT schluessel FROM client WHERE id = " ) += cId ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    Text *ret = new Text( res.values[ 0 ].getText() );
+    res.destroy();
+    return ret;
+}
+
+void ASDatenbank::unregisterKlient( int num, int sNum )
+{
+    Text *befehl = new Text( "DELETE FROM server_client WHERE client_id = " );
+    befehl->append( num );
+    befehl->append( " AND server_id = " );
+    befehl->append( sNum );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    int za = datenbank->getZeilenAnzahl();
+    unlock();
+    if( za == 1 )
+    {
+        befehl->setText( "UPDATE server SET tasks = tasks - 1 WHERE id = " );
+        befehl->append( sNum );
+        lock();
+        datenbank->befehl( befehl->getText() );
+        unlock();
+    }
+    befehl->release();
+}
+
+bool ASDatenbank::setServerStatus( int id, int status )
+{
+    Text *befehl = new Text( "UPDATE server SET server_status_id = " );
+    *befehl += status;
+    *befehl += " WHERE id = ";
+    *befehl += id;
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() != 0;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+bool ASDatenbank::setMaxClients( int id, int maxC )
+{
+    Text *befehl = new Text( "UPDATE server SET max_tasks = " );
+    befehl->append( maxC );
+    befehl->append( " WHERE id = " );
+    befehl->append( id );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() > 0;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+bool ASDatenbank::serverIstNichtPausiert( int id )
+{
+    Text *befehl = new Text( "SELECT server_status_id FROM server WHERE id = " );
+    befehl->append( id );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    bool ret = (int)res.values[ 0 ] == 3;
+    res.destroy();
+    return ret;
+}
+
+bool ASDatenbank::getChatServer( int accountId, Text *ip, int *port )
+{
+    Text *befehl = new Text( "SELECT a.port, a.ip FROM server a, server_client b, account_client c "
+        "WHERE a.server_typ_name = 'chat' AND c.client_id = b.client_id AND a.id = b.server_id AND c.account_id = " );
+    befehl->append( accountId );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    *port = TextZuInt( res.values[ 0 ].getText(), 10 );
+    ip->setText( res.values[ 1 ].getText() );
+    res.destroy();
+    return 1;
+}
+
+int ASDatenbank::gruppeErstellen( int accountId, int karteId, int *gruppe_id )
+{
+    Text *befehl = new Text( "SELECT gruppe_erstellen( " );
+    befehl->append( accountId );
+    befehl->append( ", " );
+    befehl->append( karteId );
+    befehl->append( " )" );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 6;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    if( res.zeilenAnzahl > 1 )
+        *gruppe_id = TextZuInt( res.values[ 1 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+bool ASDatenbank::gruppeAnmelden( int accountId, int gruppeId )
+{
+    Text *befehl = new Text( "SELECT * FROM gruppe WHERE id = " );
+    befehl->append( gruppeId );
+    befehl->append( " AND admin_account_id = " );
+    befehl->append( accountId );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    if( !datenbank->getZeilenAnzahl() )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    unlock();
+    befehl->setText( "SELECT gruppe_anmelden( " );
+    befehl->append( gruppeId );
+    befehl->append( " )" );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    unlock();
+    befehl->release();
+    return 1;
+}
+
+bool ASDatenbank::gruppeAbmelden( int accountId, int gruppeId )
+{
+    Text *befehl = new Text( "SELECT * FROM gruppe WHERE id = " );
+    befehl->append( gruppeId );
+    befehl->append( " AND admin_account_id = " );
+    befehl->append( accountId );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    if( !datenbank->getZeilenAnzahl() )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    unlock();
+    befehl->setText( "SELECT gruppe_abmelden( " );
+    befehl->append( gruppeId );
+    befehl->append( " )" );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    unlock();
+    befehl->release();
+    return 1;
+}
+
+bool ASDatenbank::setGruppeSpielStarten( int accountId, int gruppeId, bool starten )
+{
+    Text *befehl = new Text( "SELECT * FROM gruppe WHERE id = " );
+    befehl->append( gruppeId );
+    befehl->append( " AND admin_account_id = " );
+    befehl->append( accountId );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    if( !datenbank->getZeilenAnzahl() )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    befehl->setText( "UPDATE gruppe SET spiel_starten = " );
+    if( starten )
+        befehl->append( "TRUE" );
+    else
+        befehl->append( "FALSE" );
+    befehl->append( " WHERE id = " );
+    befehl->append( gruppeId );
+    datenbank->befehl( "BEGIN;" );
+    datenbank->befehl( "LOCK TABLE lock_table;" );
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        datenbank->befehl( "ROLLBACK;" );
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    datenbank->befehl( "COMMIT;" );
+    unlock();
+    befehl->release();
+    return 1;
+}
+
+bool ASDatenbank::getGruppeSpielStarten( int gruppeId )
+{
+    Text *befehl = new Text( "SELECT spiel_starten FROM gruppe WHERE id = " );
+    befehl->append( gruppeId );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    if( !datenbank->getZeilenAnzahl() )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    bool ret = res.values[ 0 ].istGleich( "t" );
+    res.destroy();
+    return ret;
+}
+
+bool ASDatenbank::proveEinladung( int vonAccount, int zuAccount, int gruppeId )
+{
+    Text *befehl = new Text( "SELECT * FROM gruppe WHERE id = " );
+    befehl->append( gruppeId );
+    befehl->append( " AND admin_account_id = " );
+    befehl->append( vonAccount );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    if( !datenbank->getZeilenAnzahl() )
+    {
+        unlock();
+        return 0;
+    }
+    befehl->setText( "SELECT spieler_kann_spielen( " );
+    befehl->append( zuAccount );
+    befehl->append( " )" );
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    bool ret = TextZuInt( res.values[ 0 ].getText(), 10 ) == 6;
+    res.destroy();
+    return ret;
+}
+
+int ASDatenbank::gruppeBetreten( int accountId, int gruppeId )
+{
+    Text *befehl = new Text( "SELECT spieler_betritt_gruppe( " );
+    befehl->append( accountId );
+    befehl->append( ", " );
+    befehl->append( gruppeId );
+    befehl->append( " )" );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 6;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+int ASDatenbank::gruppeVerlassen( int accountId, int gruppeId )
+{
+    Text *befehl = new Text( "SELECT spieler_verlaesst_gruppe( " );
+    befehl->append( accountId );
+    befehl->append( ", " );
+    befehl->append( gruppeId );
+    befehl->append( " )" );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+bool ASDatenbank::spielerKannKicken( int accountId, int gruppeId )
+{
+    Text *befehl = new Text( "SELECT * FROM gruppe WHERE id = " );
+    befehl->append( gruppeId );
+    befehl->append( " AND admin_account_id = " );
+    befehl->append( accountId );
+    bool ret = 1;
+    lock();
+    datenbank->befehl( befehl->getText() );
+    if( !datenbank->getZeilenAnzahl() )
+        ret = 0;
+    unlock();
+    return ret;
+}
+
+bool ASDatenbank::getSpielerInGruppe( int gruppeId, Array< int > *accountId, int *anzahl )
+{
+    Text *befehl = new Text( "SELECT account_id FROM gruppe_spieler WHERE gruppe_id = " );
+    befehl->append( gruppeId );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    *anzahl = res.zeilenAnzahl;
+    for( int i = 0; i < *anzahl; i++ )
+        accountId->add( TextZuInt( res.values[ i ].getText(), 10 ), i );
+    res.destroy();
+    return 1;
+}
+
+int ASDatenbank::getSpielerInGruppeAnzahl( int gruppeId )
+{
+    Text *befehl = new Text( "SELECT account_id FROM gruppe_spieler WHERE gruppe_id = " );
+    befehl->append( gruppeId );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    int ret = datenbank->getZeilenAnzahl();
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+int ASDatenbank::getGruppeAdminId( int gruppeId )
+{
+    Text *befehl = new Text( "SELECT admin_account_id FROM gruppe WHERE id = " );
+    befehl->append( gruppeId );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+bool ASDatenbank::gruppeSpielerEinladen( int vonAccount, int zuAccount, int gruppeId )
+{
+    if( proveEinladung( vonAccount, zuAccount, gruppeId ) )
+    {
+        Text *befehl = new Text( "INSERT INTO gruppe_einladung( gruppe_id, account_id ) VALUES( " );
+        befehl->append( gruppeId );
+        befehl->append( ", " );
+        befehl->append( zuAccount );
+        befehl->append( " )" );
+        lock();
+        if( !datenbank->befehl( befehl->getText() ) )
+        {
+            unlock();
+            befehl->release();
+            return 0;
+        }
+        unlock();
+        befehl->release();
+        return 1;
+    }
+    return 0;
+}
+
+bool ASDatenbank::gruppeEinladungAbbrechen( int admin, int gruppeId, int accountId )
+{
+    if( admin == getGruppeAdminId( gruppeId ) )
+    {
+        Text *befehl = new Text( "DELETE FROM gruppe_einladung WHERE gruppe_id =  " );
+        befehl->append( gruppeId );
+        befehl->append( " AND account_id = " );
+        befehl->append( accountId );
+        lock();
+        if( !datenbank->befehl( befehl->getText() ) )
+        {
+            unlock();
+            befehl->release();
+            return 0;
+        }
+        unlock();
+        befehl->release();
+        return 1;
+    }
+    return 0;
+}
+
+bool ASDatenbank::gruppeSpielerIstEingeladen( int gruppeId, int accountId )
+{
+    Text *befehl = new Text( "SELECT * FROM gruppe_einladung WHERE gruppe_id = " );
+    befehl->append( gruppeId );
+    befehl->append( " AND account_id = " );
+    befehl->append( accountId );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() != 0;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+bool ASDatenbank::gruppeIstInWarteschlange( int gruppeId )
+{
+    Text *befehl = new Text( "SELECT * FROM gruppe_anmeldung_fuer_spiel WHERE gruppe_id = " );
+    befehl->append( gruppeId );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() != 0;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+int ASDatenbank::getAccountId( int clientId )
+{
+    Text *befehl = new Text( "SELECT account_id FROM account_client WHERE client_id = " );
+    befehl->append( clientId );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    if( !datenbank->getZeilenAnzahl() )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+int ASDatenbank::accountAnmelden( int accountId, int karteId )
+{
+    Text *befehl = new Text( "SELECT account_anmelden( " );
+    befehl->append( accountId );
+    befehl->append( ", " );
+    befehl->append( karteId );
+    befehl->append( " )" );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 6;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+void ASDatenbank::accountAbmelden( int accountId )
+{
+    Text *befehl = new Text( "SELECT account_abmelden( " );
+    befehl->append( accountId );
+    befehl->append( " )" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    unlock();
+    befehl->release();
+}
+
+bool ASDatenbank::spielerBesitztKarte( int accountId, int karteId )
+{
+    Text *befehl = new Text( "SELECT a.account_id FROM spiel_art_account a, karte_account b, karte c WHERE a.account_id = " );
+    befehl->append( accountId );
+    befehl->append( " AND a.spiel_art_id = c.spiel_art_id AND b.karte_id = c.id AND b.account_id = a.account_id AND c.id = " );
+    befehl->append( karteId );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    int zeilen = datenbank->getZeilenAnzahl();
+    unlock();
+    befehl->release();
+    return zeilen != 0;
+}
+
+int ASDatenbank::getGruppenKarte( int gruppeId )
+{
+    Text *befehl = new Text( "SELECT karte_id FROM gruppe WHERE id = " );
+    befehl->append( gruppeId );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+Text *ASDatenbank::getAccountRufName( int accountId )
+{
+    Text *befehl = new Text( "SELECT ruf_name FROM account WHERE id = " );
+    befehl->append( accountId );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return new Text( "" );
+    }
+    Text *ret = new Text( res.values[ 0 ].getText() );
+    res.destroy();
+    return ret;
+}
+
+// constant
+Text *ASDatenbank::getLetzterFehler() const
+{
+    return datenbank->getLetzterFehler();
+}
+
+// Reference Counting
+ASDatenbank *ASDatenbank::getThis()
+{
+    ref++;
+    return this;
+}
+
+ASDatenbank *ASDatenbank::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 73 - 0
AnmeldungServer/Datenbank.h

@@ -0,0 +1,73 @@
+#ifndef Datenbank_H
+#define Datenbank_H
+
+#include <sql.h>
+#include <Text.h>
+#include <Array.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+using namespace sql;
+
+namespace Admin_Recht
+{
+	const int ASStarten = 28;
+	const int ASBeenden = 29;
+	const int ASPausieren = 30;
+	const int ASMCChange = 31;
+}
+
+class ASDatenbank
+{
+private:
+	Datenbank *datenbank;
+	CRITICAL_SECTION cs;
+	int ref;
+
+public:
+	// Konstruktor
+	ASDatenbank( InitDatei *zIni );
+	// Destruktor
+	~ASDatenbank();
+	// nicht constant
+	void lock();
+	void unlock();
+	int istAdministrator( const char *name, const char *passwort );
+	bool adminHatRecht( int id, int recht );
+	bool proveKlient( int num, int sNum );
+	Text *getKlientKey( int cId );
+	void unregisterKlient( int num, int sNum );
+	bool setServerStatus( int id, int status );
+	bool setMaxClients( int id, int maxC );
+	bool serverIstNichtPausiert( int id );
+	bool getChatServer( int accountId, Text *ip, int *port );
+	int gruppeErstellen( int accountId, int karteId, int *gruppe_id );
+	bool gruppeAnmelden( int accountId, int gruppeId );
+	bool gruppeAbmelden( int accountId, int gruppeId );
+	bool setGruppeSpielStarten( int accountId, int gruppeId, bool starten );
+	bool getGruppeSpielStarten( int gruppeId );
+	bool proveEinladung( int vonAccount, int zuAccount, int gruppeId );
+	int gruppeBetreten( int accountId, int gruppeId );
+	int gruppeVerlassen( int accountId, int gruppeId );
+	bool spielerKannKicken( int accountId, int gruppeId );
+	bool getSpielerInGruppe( int gruppeId, Array< int > *accountId, int *anzahl );
+	int getSpielerInGruppeAnzahl( int gruppeId );
+	int getGruppeAdminId( int gruppeId );
+	bool gruppeSpielerEinladen( int vonAccount, int zuAccount, int gruppeId );
+	bool gruppeEinladungAbbrechen( int admin, int gruppeId, int accountId );
+	bool gruppeSpielerIstEingeladen( int gruppeId, int accountId );
+	bool gruppeIstInWarteschlange( int gruppeId );
+	int getAccountId( int clientId );
+	int accountAnmelden( int accountId, int karteId );
+	void accountAbmelden( int accountId );
+	bool spielerBesitztKarte( int accountId, int karteId );
+	int getGruppenKarte( int gruppeId );
+	Text *getAccountRufName( int accountId );
+	// constant
+	Text *getLetzterFehler() const;
+	// Reference Counting
+	ASDatenbank *getThis();
+	ASDatenbank *release();
+};
+
+#endif

+ 57 - 0
AnmeldungServer/main.cpp

@@ -0,0 +1,57 @@
+#include "AnmeldungServer.h"
+#include <Zeit.h>
+#include <iostream>
+#include <fstream>
+#include <Globals.h>
+
+int main()
+{
+#ifdef DEBUG
+    cd( "/test/anmeldung" );
+#endif
+    Framework::initFramework();
+    Zeit *z = getZeit();
+    Text *pfad = new Text( "../log/anmeldung/" );
+    pfad->append( z->getZeit( "y-m-d h-i-s.log" ) );
+    z->release();
+    DateiPfadErstellen( pfad->getThis() );
+    std::ofstream file;
+    file.open( pfad->getText() );
+    std::streambuf* sbuf = std::cout.rdbuf();
+    std::cout.rdbuf( file.rdbuf() );
+    pfad->release();
+
+    std::cout << "AS: Startet...\n";
+    std::cout << "AS: Lese init Datei ../data/asInit.ini ...\n";
+    InitDatei *dat = new InitDatei( "../data/asInit.ini" );
+    if( !dat->laden() )
+    {
+        std::cout << "AS: error: Datei konnte nicht gelesen werden. Das Programm wird geschlossen.\n";
+        dat->release();
+        exit( 1 );
+    }
+    const char *wichtig[] = { "ServerId", "DBBenutzer", "DBPasswort", "DBName", "DBIP", "DBPort", "Aktiv" };
+    for( const char *w : wichtig )
+    {
+        if( !dat->wertExistiert( w ) )
+        {
+            std::cout << "AS: error: Der Wert '" << w << "' wurde nicht gefunden. Das Programm wird geschlossen.\n";
+            dat->release();
+            exit( 1 );
+        }
+    }
+
+    AnmeldungServer *aServer = new AnmeldungServer( dat );
+
+    std::cout << "AS: Der Admin Server läuft. Startforgang beendet.\n";
+    aServer->runn();
+
+    aServer->ende();
+    aServer->release();
+    dat->release();
+    std::cout << "AS: Der Server ist heruntergefahren.\n";
+    file.close();
+    std::cout.rdbuf( sbuf );
+    Framework::releaseFramework();
+    return 0;
+}

BIN
AnmeldungServer/readme/images/ArchOptions.gif


BIN
AnmeldungServer/readme/images/ChangeRemote.gif


BIN
AnmeldungServer/readme/images/ManageConnections.gif


BIN
AnmeldungServer/readme/images/OutputTypes.gif


BIN
AnmeldungServer/readme/images/debuggerexport.png


BIN
AnmeldungServer/readme/images/firstconnection.png


BIN
AnmeldungServer/readme/images/linker.png


BIN
AnmeldungServer/readme/images/postbuild.png


+ 85 - 0
AnmeldungServer/readme/readme.html

@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset='utf-8'>
+
+    <link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
+
+    <title>Getting Started</title>
+  </head>
+
+<body>
+
+    <div class="container">
+        <div id="header">
+            <h1>Getting Started</h1>
+            <h2>Visual C++ for Linux Development extension</h2>
+        </div>
+    
+    <table>
+    <tr>    
+    <div id="main_content">
+        
+        <td>
+        <div id="lpanel">
+            <h1>Setting up your project for Linux Development</h1>
+
+            <p>With this extension you can author C++ code for Linux servers, desktops and devices. You can manage your connections to these machines from within VS. VS will automatically copy and remote build your sources and can launch your application with the debugger. Our project system supports targeting specific architectures, including ARM.</p>
+            <img src="images\ArchOptions.gif"/>
+            
+            <h1>Connecting to Linux</h1>
+            <h2>Prerequisites</h2>
+            <p>Today we only support building remotely on the Linux target machine. We are not limited by specific Linux distros but we do have dependencies on the presence of some tools. Specifically, we need openssh-server, g++, gdb and gdbserver. Use your favorite package manager to install them, e.g. on Debian based systems: sudo apt-get install openssh-server g++ gdb gdbserver</p>
+            
+            <h2>First connection</h2>
+            <p>The first time you target a Linux machine you will be prompted for connection information.  This is triggered by building the project.</p>
+            <img src="images\firstconnection.png"/>
+                
+            <h2>Adding and removing connections</h2>
+            <p>To add a new connection, go to Tools > Options and search for Linux. From here you can add and remove connections.</p>
+            <img src="images\ManageConnections.gif"/>
+            
+            <p>To change which connection a project is using go to the project properties remote settings and update the target machine.</p>
+            <img src="images\ChangeRemote.gif"/>
+            
+            <h1>Project Properties</h1>
+            <p>All of the options necessary to control C++ compilation are exposed on the project properies pages. We'll cover a few specific to how things work for Linux. First under remote settings, you will see the remote root is set to ~/projects/ by default and that we are setting the remote project directory to match our project name in that location. </p>
+            <img src="images\OutputTypes.gif"/>
+            
+            <p>Looking at the General settings for the project, you can see how our output and intermediate directories were configured. Additionally, you’ll see that this project was configured as an application – thus our executable is under bin/x64/Debug/ as ConsoleApplication1.out. Notice that for configuration types we also support static and dynamic libraries.</p>
+            
+            <p>Add additional library dependencies on the Linker > Input property page.</p>
+            <img src="images\linker.png"/>
+            
+            <p>You can pass additional pre launch commands to the debugger to do things like launch graphical apps on the remote linux machine.</p>
+            <img src="images\debuggerexport.png"/>
+            
+            <p>You can also send post build events to control remote behavior, as in this example that exports a gpio pin for use without requiring the executable run as super user.</p>
+            <img src="images\postbuild.png"/>
+            
+        </div>
+        </td>
+        <td>
+        <div id="rpanel">
+
+            <h1>Resources</h1>
+
+            <p>Check out the <a href="http://aka.ms/vslinuxext">VS Gallery VC++ for Linux Development page</a> where we will keep updates posted. You can also check out our <a href="https://blogs.msdn.microsoft.com/vcblog/2016/03/30/visual-c-for-linux-development">announcment blog post</a> for more in depth details on configuring the project properties.</p>
+            
+            <p>Here are other utilities you will find useful in connection with this extension.</p>
+            <ul>
+                <li>Learn more about <a href="http://aka.ms/vsiot">IoT Development</a></li>
+                <li><a href="http://aka.ms/vsiotext">VC++ for IoT Development Tools</a></li>
+                <li><a href="https://github.com/Azure/azure-iot-sdks">Azure IoT SDK</a>, includes a C API for connecting small devices to the Azure IoT Hub</li>
+            </ul>
+
+            <h1>Give us feedback</h1>
+            <p><a href="http://aka.ms/vslinux-feedback">UserVoice</a></p>
+        </div>
+        </td>   
+    </div>
+    </tr>
+    </table>
+    </div>
+</body>
+</html>

+ 119 - 0
AnmeldungServer/readme/stylesheet.css

@@ -0,0 +1,119 @@
+body {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  color: #1E1E1E;
+  font-size: 13px;
+  font-family: "Segoe UI", Helvetica, Arial, sans-serif;
+  line-height: 1.45;
+  word-wrap: break-word;
+}
+
+/* General & 'Reset' Stuff */
+
+
+.container {
+  width: 1100px;
+  margin: 0 auto;
+}
+
+section {
+  display: block;
+  margin: 0;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  margin: 0;
+}
+
+table, tr {
+    width: 1100px;
+    padding: 0px;
+    vertical-align: top;
+  }
+
+/* Header, <header>
+   header   - container
+   h1       - project name
+   h2       - project description
+*/
+
+#header {
+  color: #FFF;
+  background: #68217a;
+  position:relative;
+}
+h1, h2 {
+  font-family: "Segoe UI Light", "Segoe UI", Helvetica, Arial, sans-serif;
+  line-height: 1;
+  margin: 0 18px;;
+  padding: 0;
+}
+#header h1 {
+  font-size: 3.4em;
+  padding-top: 18px;
+  font-weight: normal;
+  margin-left: 15px;
+}
+
+#header h2 {
+  font-size: 1.5em;
+  margin-top: 10px;
+  padding-bottom: 18px;
+  font-weight: normal;
+}
+
+#main_content {
+  width: 100%;
+  display: flex;
+  flex-direction: row;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+  font-weight: bolder;
+}
+
+#main_content h1 {
+  font-size: 1.8em;
+  margin-top: 34px;
+}
+
+    #main_content h1:first-child {
+        margin-top: 30px;
+    }
+
+#main_content h2 {
+  font-size: 1.8em;
+}
+p, ul {
+    margin: 11px 18px;
+}
+
+#main_content a {
+    color: #06C;
+    text-decoration: none;
+}
+ul {
+        margin-top: 13px;
+    margin-left: 18px;
+    padding-left: 0;
+}
+    ul li {
+        margin-left: 18px;
+        padding-left: 0;
+    }
+#lpanel {
+    width: 870px;
+    float: left;
+}
+#rpanel ul {
+    list-style-type: none;
+}
+    #rpanel ul li {
+        line-height: 1.8em;
+    }
+#rpanel {
+    background: #e7e7e7;
+    width: 230px;
+}

+ 2 - 0
build.bat

@@ -0,0 +1,2 @@
+"D:\Visual Studio 2017\MSBuild\15.0\Bin\MSBuild.exe" "Anmeldung Server.sln" /t:rebuild /p:configuration=debug /p:platform=x64
+"D:\Visual Studio 2017\MSBuild\15.0\Bin\MSBuild.exe" "Anmeldung Server.sln" /t:rebuild /p:configuration=release /p:platform=x64

+ 11 - 0
data/asInit.ini

@@ -0,0 +1,11 @@
+DBBenutzer=anmeldungserveru
+DBPasswort=LTAnmeldungServerPW
+DBName=test_db
+DBIP=127.0.0.1
+DBPort=5432
+ServerName=Test
+ServerPort=49140
+ServerIP=192.168.178.41
+AdminServerPort=49139
+Aktiv=FALSE
+MaxClients=50