Browse Source

Projektdateien hinzufügen.

Kolja Strohm 7 years ago
parent
commit
44240c3e35

+ 7 - 0
Data/msInit.ini

@@ -0,0 +1,7 @@
+DBBenutzer=mainserveru
+DBPasswort=LTMainServerPW
+DBName=koljadb
+DBIP=127.0.0.1
+DBPort=5432
+MSPort=4253
+MSAPort=4252

+ 30 - 0
Main 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}") = "MainServer", "MainServer\MainServer.vcxproj", "{39533D13-F0AB-4243-B957-CDBC8BE7EBF4}"
+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
+		{39533D13-F0AB-4243-B957-CDBC8BE7EBF4}.Debug|ARM.ActiveCfg = Debug|x64
+		{39533D13-F0AB-4243-B957-CDBC8BE7EBF4}.Debug|x64.ActiveCfg = Debug|x64
+		{39533D13-F0AB-4243-B957-CDBC8BE7EBF4}.Debug|x64.Build.0 = Debug|x64
+		{39533D13-F0AB-4243-B957-CDBC8BE7EBF4}.Debug|x86.ActiveCfg = Debug|x64
+		{39533D13-F0AB-4243-B957-CDBC8BE7EBF4}.Release|ARM.ActiveCfg = Release|x64
+		{39533D13-F0AB-4243-B957-CDBC8BE7EBF4}.Release|x64.ActiveCfg = Release|x64
+		{39533D13-F0AB-4243-B957-CDBC8BE7EBF4}.Release|x64.Build.0 = Release|x64
+		{39533D13-F0AB-4243-B957-CDBC8BE7EBF4}.Release|x86.ActiveCfg = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 1225 - 0
MainServer/Datenbank.cpp

@@ -0,0 +1,1225 @@
+#include "Datenbank.h"
+#include <iostream>
+
+// Inhalt der MSDatenbank Klasse aus Datenbank.h
+// Konstruktor
+MSDatenbank::MSDatenbank( InitDatei *zDat )
+{
+	if( !zDat->wertExistiert( "DBBenutzer" ) )
+		zDat->addWert( "DBBenutzer", "mainserveru" );
+	if( !zDat->wertExistiert( "DBPasswort" ) )
+		zDat->addWert( "DBPasswort", "LTMainServerPW" );
+	if( !zDat->wertExistiert( "DBName" ) )
+		zDat->addWert( "DBName", "koljadb" );
+	if( !zDat->wertExistiert( "DBIP" ) )
+		zDat->addWert( "DBIP", "127.0.0.1" );
+	if( !zDat->wertExistiert( "DBPort" ) )
+		zDat->addWert( "DBPort", "5432" );
+	datenbank = new Datenbank( zDat->zWert( "DBBenutzer" )->getText(), zDat->zWert( "DBPasswort" )->getText(),
+							   zDat->zWert( "DBName" )->getText(), zDat->zWert( "DBIP" )->getText(),
+							   (unsigned short)TextZuInt( zDat->zWert( "DBPort" )->getText(), 10 ) );
+	if( !datenbank->istOk() )
+	{
+		std::cout << "MS: Es konnte keine Verbindung zur Datenbank hergestellt werden:\n";
+		Text *txt = datenbank->getLetzterFehler();
+		std::cout << txt->getText() << "\nDas Programm wird beendet.";
+		txt->release();
+		exit( 1 );
+	}
+	InitializeCriticalSection( &ths );
+	ref = 1;
+}
+
+// Detruktor
+MSDatenbank::~MSDatenbank()
+{
+	datenbank->release();
+	DeleteCriticalSection( &ths );
+}
+
+// nicht constant
+void MSDatenbank::lock()
+{
+	EnterCriticalSection( &ths );
+}
+
+void MSDatenbank::unlock()
+{
+	LeaveCriticalSection( &ths );
+}
+
+int MSDatenbank::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 = '" );
+	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 MSDatenbank::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;
+}
+
+unsigned int MSDatenbank::getNextClientId()
+{
+	lock();
+	if( !datenbank->befehl( "SELECT get_next_client_id()" ) )
+	{
+		unlock();
+		return 0;
+	}
+	Result res = datenbank->getResult();
+	unlock();
+	unsigned int ret = (unsigned int)TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+Text *MSDatenbank::getKlientKey( int cId )
+{
+	lock();
+	if( !datenbank->befehl( Text( "SELECT schluessel FROM clients 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;
+}
+
+bool MSDatenbank::proveRegisteredClient( unsigned int num )
+{
+	Text *befehl = new Text( "SELECT * FROM clients WHERE id = " );
+	befehl->append( num );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	bool ret = res.zeilenAnzahl == 1;
+	res.destroy();
+	return ret;
+}
+
+int *MSDatenbank::unregisterClient( unsigned int num )
+{
+	Text *befehl = new Text( "SELECT unregister_client( " );
+	befehl->append( num );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	int *ret = new int[ res.zeilenAnzahl ];
+	for( int i = 0; i < res.zeilenAnzahl; i++ )
+		ret[ i ] = TextZuInt( res.values[ i ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+int MSDatenbank::suchPatchServer( unsigned int client )
+{
+	Text *befehl = new Text( "SELECT such_patch_server( " );
+	befehl->append( client );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+unsigned char *MSDatenbank::getPatchServerPortIp( int num )
+{
+	Text *befehl = new Text( "SELECT port, ip FROM server_patch WHERE id = " );
+	befehl->append( num );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	unsigned short port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	Text *ip1 = res.values[ 1 ].getTeilText( 0, res.values[ 1 ].positionVon( '.', 0 ) );
+	Text *ip2 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 0 ) + 1, res.values[ 1 ].positionVon( '.', 1 ) );
+	Text *ip3 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 1 ) + 1, res.values[ 1 ].positionVon( '.', 2 ) );
+	Text *ip4 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 2 ) + 1 );
+	res.destroy();
+	unsigned char *ret = new unsigned char[ 6 ];
+	ret[ 0 ] = (unsigned char)TextZuInt( ip1->getText(), 10 );
+	ret[ 1 ] = (unsigned char)TextZuInt( ip2->getText(), 10 );
+	ret[ 2 ] = (unsigned char)TextZuInt( ip3->getText(), 10 );
+	ret[ 3 ] = (unsigned char)TextZuInt( ip4->getText(), 10 );
+	ret[ 4 ] = (unsigned char)( port & 0xFF );
+	ret[ 5 ] = (unsigned char)( port >> 8 );
+	ip1->release();
+	ip2->release();
+	ip3->release();
+	ip4->release();
+	return ret;
+}
+
+int MSDatenbank::suchRegisterServer( unsigned int client )
+{
+	Text *befehl = new Text( "SELECT such_register_server( " );
+	befehl->append( client );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+unsigned char *MSDatenbank::getRegisterServerPortIp( int num )
+{
+	Text *befehl = new Text( "SELECT port, ip FROM server_register WHERE id = " );
+	befehl->append( num );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	unsigned short port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	Text *ip1 = res.values[ 1 ].getTeilText( 0, res.values[ 1 ].positionVon( '.', 0 ) );
+	Text *ip2 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 0 ) + 1, res.values[ 1 ].positionVon( '.', 1 ) );
+	Text *ip3 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 1 ) + 1, res.values[ 1 ].positionVon( '.', 2 ) );
+	Text *ip4 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 2 ) + 1 );
+	res.destroy();
+	unsigned char *ret = new unsigned char[ 6 ];
+	ret[ 0 ] = (unsigned char)TextZuInt( ip1->getText(), 10 );
+	ret[ 1 ] = (unsigned char)TextZuInt( ip2->getText(), 10 );
+	ret[ 2 ] = (unsigned char)TextZuInt( ip3->getText(), 10 );
+	ret[ 3 ] = (unsigned char)TextZuInt( ip4->getText(), 10 );
+	ret[ 4 ] = (unsigned char)( port & 0xFF );
+	ret[ 5 ] = (unsigned char)( port >> 8 );
+	ip1->release();
+	ip2->release();
+	ip3->release();
+	ip4->release();
+	return ret;
+}
+
+int MSDatenbank::suchLoginServer( unsigned int client )
+{
+	Text *befehl = new Text( "SELECT such_login_server( " );
+	befehl->append( client );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+unsigned char *MSDatenbank::getLoginServerPortIp( int num )
+{
+	Text *befehl = new Text( "SELECT port, ip FROM server_login WHERE id = " );
+	befehl->append( num );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	unsigned short port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	Text *ip1 = res.values[ 1 ].getTeilText( 0, res.values[ 1 ].positionVon( '.', 0 ) );
+	Text *ip2 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 0 ) + 1, res.values[ 1 ].positionVon( '.', 1 ) );
+	Text *ip3 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 1 ) + 1, res.values[ 1 ].positionVon( '.', 2 ) );
+	Text *ip4 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 2 ) + 1 );
+	res.destroy();
+	unsigned char *ret = new unsigned char[ 6 ];
+	ret[ 0 ] = (unsigned char)TextZuInt( ip1->getText(), 10 );
+	ret[ 1 ] = (unsigned char)TextZuInt( ip2->getText(), 10 );
+	ret[ 2 ] = (unsigned char)TextZuInt( ip3->getText(), 10 );
+	ret[ 3 ] = (unsigned char)TextZuInt( ip4->getText(), 10 );
+	ret[ 4 ] = (unsigned char)( port & 0xFF );
+	ret[ 5 ] = (unsigned char)( port >> 8 );
+	ip1->release();
+	ip2->release();
+	ip3->release();
+	ip4->release();
+	return ret;
+}
+
+int MSDatenbank::suchInformationServer( unsigned int client )
+{
+	Text *befehl = new Text( "SELECT such_information_server( " );
+	befehl->append( client );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+unsigned char *MSDatenbank::getInformationServerPortIp( int num )
+{
+	Text *befehl = new Text( "SELECT port, ip FROM server_information WHERE id = " );
+	befehl->append( num );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	unsigned short port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	Text *ip1 = res.values[ 1 ].getTeilText( 0, res.values[ 1 ].positionVon( '.', 0 ) );
+	Text *ip2 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 0 ) + 1, res.values[ 1 ].positionVon( '.', 1 ) );
+	Text *ip3 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 1 ) + 1, res.values[ 1 ].positionVon( '.', 2 ) );
+	Text *ip4 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 2 ) + 1 );
+	res.destroy();
+	unsigned char *ret = new unsigned char[ 6 ];
+	ret[ 0 ] = (unsigned char)TextZuInt( ip1->getText(), 10 );
+	ret[ 1 ] = (unsigned char)TextZuInt( ip2->getText(), 10 );
+	ret[ 2 ] = (unsigned char)TextZuInt( ip3->getText(), 10 );
+	ret[ 3 ] = (unsigned char)TextZuInt( ip4->getText(), 10 );
+	ret[ 4 ] = (unsigned char)( port & 0xFF );
+	ret[ 5 ] = (unsigned char)( port >> 8 );
+	ip1->release();
+	ip2->release();
+	ip3->release();
+	ip4->release();
+	return ret;
+}
+
+int MSDatenbank::suchChatServer( unsigned int client )
+{
+	Text *befehl = new Text( "SELECT such_chat_server( " );
+	befehl->append( client );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+unsigned char *MSDatenbank::getChatServerPortIp( int num )
+{
+	Text *befehl = new Text( "SELECT port, ip FROM server_chat WHERE id = " );
+	befehl->append( num );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	unsigned short port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	Text *ip1 = res.values[ 1 ].getTeilText( 0, res.values[ 1 ].positionVon( '.', 0 ) );
+	Text *ip2 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 0 ) + 1, res.values[ 1 ].positionVon( '.', 1 ) );
+	Text *ip3 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 1 ) + 1, res.values[ 1 ].positionVon( '.', 2 ) );
+	Text *ip4 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 2 ) + 1 );
+	res.destroy();
+	unsigned char *ret = new unsigned char[ 6 ];
+	ret[ 0 ] = (unsigned char)TextZuInt( ip1->getText(), 10 );
+	ret[ 1 ] = (unsigned char)TextZuInt( ip2->getText(), 10 );
+	ret[ 2 ] = (unsigned char)TextZuInt( ip3->getText(), 10 );
+	ret[ 3 ] = (unsigned char)TextZuInt( ip4->getText(), 10 );
+	ret[ 4 ] = (unsigned char)( port & 0xFF );
+	ret[ 5 ] = (unsigned char)( port >> 8 );
+	ip1->release();
+	ip2->release();
+	ip3->release();
+	ip4->release();
+	return ret;
+}
+
+int MSDatenbank::suchAnmeldungServer( unsigned int client )
+{
+	Text *befehl = new Text( "SELECT such_anmeldung_server( " );
+	befehl->append( client );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+unsigned char *MSDatenbank::getAnmeldungServerPortIp( int num )
+{
+	Text *befehl = new Text( "SELECT port, ip FROM server_anmeldung WHERE id = " );
+	befehl->append( num );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	unsigned short port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	Text *ip1 = res.values[ 1 ].getTeilText( 0, res.values[ 1 ].positionVon( '.', 0 ) );
+	Text *ip2 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 0 ) + 1, res.values[ 1 ].positionVon( '.', 1 ) );
+	Text *ip3 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 1 ) + 1, res.values[ 1 ].positionVon( '.', 2 ) );
+	Text *ip4 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 2 ) + 1 );
+	res.destroy();
+	unsigned char *ret = new unsigned char[ 6 ];
+	ret[ 0 ] = (unsigned char)TextZuInt( ip1->getText(), 10 );
+	ret[ 1 ] = (unsigned char)TextZuInt( ip2->getText(), 10 );
+	ret[ 2 ] = (unsigned char)TextZuInt( ip3->getText(), 10 );
+	ret[ 3 ] = (unsigned char)TextZuInt( ip4->getText(), 10 );
+	ret[ 4 ] = (unsigned char)( port & 0xFF );
+	ret[ 5 ] = (unsigned char)( port >> 8 );
+	ip1->release();
+	ip2->release();
+	ip3->release();
+	ip4->release();
+	return ret;
+}
+
+int MSDatenbank::suchErhaltungServer( unsigned int client )
+{
+	Text *befehl = new Text( "SELECT such_erhaltung_server( " );
+	befehl->append( client );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+unsigned char *MSDatenbank::getErhaltungServerPortIp( int num )
+{
+	Text *befehl = new Text( "SELECT port, ip FROM server_erhaltung WHERE id = " );
+	befehl->append( num );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	unsigned short port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	Text *ip1 = res.values[ 1 ].getTeilText( 0, res.values[ 1 ].positionVon( '.', 0 ) );
+	Text *ip2 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 0 ) + 1, res.values[ 1 ].positionVon( '.', 1 ) );
+	Text *ip3 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 1 ) + 1, res.values[ 1 ].positionVon( '.', 2 ) );
+	Text *ip4 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 2 ) + 1 );
+	res.destroy();
+	unsigned char *ret = new unsigned char[ 6 ];
+	ret[ 0 ] = (unsigned char)TextZuInt( ip1->getText(), 10 );
+	ret[ 1 ] = (unsigned char)TextZuInt( ip2->getText(), 10 );
+	ret[ 2 ] = (unsigned char)TextZuInt( ip3->getText(), 10 );
+	ret[ 3 ] = (unsigned char)TextZuInt( ip4->getText(), 10 );
+	ret[ 4 ] = (unsigned char)( port & 0xFF );
+	ret[ 5 ] = (unsigned char)( port >> 8 );
+	ip1->release();
+	ip2->release();
+	ip3->release();
+	ip4->release();
+	return ret;
+}
+
+int MSDatenbank::suchShopServer( unsigned int client )
+{
+	Text *befehl = new Text( "SELECT such_shop_server( " );
+	befehl->append( client );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+unsigned char *MSDatenbank::getShopServerPortIp( int num )
+{
+	Text *befehl = new Text( "SELECT port, ip FROM server_shop WHERE id = " );
+	befehl->append( num );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	unsigned short port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	Text *ip1 = res.values[ 1 ].getTeilText( 0, res.values[ 1 ].positionVon( '.', 0 ) );
+	Text *ip2 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 0 ) + 1, res.values[ 1 ].positionVon( '.', 1 ) );
+	Text *ip3 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 1 ) + 1, res.values[ 1 ].positionVon( '.', 2 ) );
+	Text *ip4 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 2 ) + 1 );
+	res.destroy();
+	unsigned char *ret = new unsigned char[ 6 ];
+	ret[ 0 ] = (unsigned char)TextZuInt( ip1->getText(), 10 );
+	ret[ 1 ] = (unsigned char)TextZuInt( ip2->getText(), 10 );
+	ret[ 2 ] = (unsigned char)TextZuInt( ip3->getText(), 10 );
+	ret[ 3 ] = (unsigned char)TextZuInt( ip4->getText(), 10 );
+	ret[ 4 ] = (unsigned char)( port & 0xFF );
+	ret[ 5 ] = (unsigned char)( port >> 8 );
+	ip1->release();
+	ip2->release();
+	ip3->release();
+	ip4->release();
+	return ret;
+}
+
+int MSDatenbank::suchNewsServer( unsigned int client )
+{
+	Text *befehl = new Text( "SELECT such_news_server( " );
+	befehl->append( client );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+unsigned char *MSDatenbank::getNewsServerPortIp( int num )
+{
+	Text *befehl = new Text( "SELECT port, ip FROM server_news WHERE id = " );
+	befehl->append( num );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	befehl->release();
+	Result res = datenbank->getResult();
+	unlock();
+	unsigned short port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	Text *ip1 = res.values[ 1 ].getTeilText( 0, res.values[ 1 ].positionVon( '.', 0 ) );
+	Text *ip2 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 0 ) + 1, res.values[ 1 ].positionVon( '.', 1 ) );
+	Text *ip3 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 1 ) + 1, res.values[ 1 ].positionVon( '.', 2 ) );
+	Text *ip4 = res.values[ 1 ].getTeilText( res.values[ 1 ].positionVon( '.', 2 ) + 1 );
+	res.destroy();
+	unsigned char *ret = new unsigned char[ 6 ];
+	ret[ 0 ] = (unsigned char)TextZuInt( ip1->getText(), 10 );
+	ret[ 1 ] = (unsigned char)TextZuInt( ip2->getText(), 10 );
+	ret[ 2 ] = (unsigned char)TextZuInt( ip3->getText(), 10 );
+	ret[ 3 ] = (unsigned char)TextZuInt( ip4->getText(), 10 );
+	ret[ 4 ] = (unsigned char)( port & 0xFF );
+	ret[ 5 ] = (unsigned char)( port >> 8 );
+	ip1->release();
+	ip2->release();
+	ip3->release();
+	ip4->release();
+	return ret;
+}
+
+int MSDatenbank::logoutKlient( int klientId, Array< int > *ret )
+{
+	Text *befehl = new Text( "SELECT logout_client( " );
+	befehl->append( klientId );
+	befehl->append( " )" );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	for( int i = 0; i < res.zeilenAnzahl; i++ )
+		ret->set( TextZuInt( res.values[ i ].getText(), 10 ), i );
+	int retVal = res.zeilenAnzahl;
+	res.destroy();
+	return retVal;
+}
+
+bool MSDatenbank::getSpielServerPortIp( int spielErstelltId, unsigned short *port, Text *ip )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_spiel a, spiel_erstellt b "
+							 "WHERE a.id = b.server_spiel_id AND b.id = " );
+	befehl->append( spielErstelltId );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	*port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	ip->setText( res.values[ 1 ].getText() );
+	res.destroy();
+	return 1;
+}
+
+int MSDatenbank::getSpielerAusGruppe( int gruppeId, Array< int > *accountId )
+{
+	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();
+	int ret = res.zeilenAnzahl;
+	for( int i = 0; i < ret; i++ )
+		accountId->add( TextZuInt( res.values[ i ].getText(), 10 ), i );
+	return ret;
+}
+
+int MSDatenbank::kickSpielerAusGruppe( int gruppeId, int accountId )
+{
+	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 MSDatenbank::getChatServerPortIp( int accountId, unsigned short *port, Text *ip )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_chat AS a, server_chat_clients AS b, account_clients AS c "
+							 "WHERE c.client_id = b.client_id AND a.id = b.server_chat_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();
+	*port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	ip->setText( res.values[ 1 ].getText() );
+	res.destroy();
+	return 1;
+}
+
+int MSDatenbank::getGruppeAdmin( 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;
+}
+
+int MSDatenbank::getSpielerAusChatroom( int chatroomId, Array< int > *accountId )
+{
+	Text *befehl = new Text( "SELECT account_id FROM chatroom_spieler WHERE chatroom_id = " );
+	befehl->append( chatroomId );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	int ret = res.zeilenAnzahl;
+	for( int i = 0; i < ret; i++ )
+		accountId->add( TextZuInt( res.values[ i ].getText(), 10 ), i );
+	return ret;
+}
+
+int MSDatenbank::getChatroomAdmin( int chatroomId )
+{
+	Text *befehl = new Text( "SELECT admin_account_id FROM chatroom WHERE id = " );
+	befehl->append( chatroomId );
+	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;
+}
+
+int MSDatenbank::clientistEingeloggt( int clientId )
+{
+	Text *befehl = new Text( "SELECT account_id FROM account_clients WHERE client_id = " );
+	befehl->append( clientId );
+	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 MSDatenbank::getPatchServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_patch AS a, server_patch_clients AS b "
+							 "WHERE a.id = b.server_patch_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+bool MSDatenbank::getRegisterServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_register AS a, server_register_clients AS b "
+							 "WHERE a.id = b.server_register_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+bool MSDatenbank::getLoginServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_login AS a, server_login_clients AS b "
+							 "WHERE a.id = b.server_login_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+bool MSDatenbank::getInformationServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_information AS a, server_information_clients AS b "
+							 "WHERE a.id = b.server_information_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+bool MSDatenbank::getChatServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_chat AS a, server_chat_clients AS b "
+							 "WHERE a.id = b.server_chat_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+bool MSDatenbank::getAnmeldungServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_anmeldung AS a, server_anmeldung_clients AS b "
+							 "WHERE a.id = b.server_anmeldung_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+bool MSDatenbank::getSpielServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT account_id FROM account_clients WHERE client_id = " );
+	befehl->append( client );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	Result res = datenbank->getResult();
+	unlock();
+	if( !res.zeilenAnzahl )
+	{
+		res.destroy();
+		befehl->release();
+		return 0;
+	}
+	int accountId = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	befehl->setText( "SELECT a.id FROM spiel a, spiel_spieler b WHERE b.spiel_id = a.id "
+					 "AND a.spiel_status_id < 3 AND b.spiel_spieler_status_id = 5 AND b.account_id = " );
+	befehl->append( accountId );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	res = datenbank->getResult();
+	unlock();
+	if( !res.zeilenAnzahl )
+	{
+		res.destroy();
+		befehl->release();
+		return 0;
+	}
+	int spielId = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	befehl->setText( "SELECT spiel_server_id FROM spiel WHERE id = " );
+	befehl->append( spielId );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	res = datenbank->getResult();
+	unlock();
+	if( !res.zeilenAnzahl )
+	{
+		res.destroy();
+		befehl->release();
+		return 0;
+	}
+	int serverId = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	befehl->setText( "SELECT port, ip FROM server_spiel WHERE id = " );
+	befehl->append( serverId );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	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;
+}
+
+bool MSDatenbank::getShopServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_shop AS a, server_shop_clients AS b "
+							 "WHERE a.id = b.server_shop_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+bool MSDatenbank::getNewsServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_news AS a, server_news_clients AS b "
+							 "WHERE a.id = b.server_news_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+bool MSDatenbank::getHistorieServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_historie AS a, server_historie_clients AS b "
+							 "WHERE a.id = b.server_historie_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+bool MSDatenbank::getKartenServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_karten AS a, server_karten_clients AS b "
+							 "WHERE a.id = b.server_karten_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+bool MSDatenbank::getEditorServer( int client, Text *ip, int *port )
+{
+	Text *befehl = new Text( "SELECT a.port, a.ip FROM server_editor AS a, server_editor_clients AS b "
+							 "WHERE a.id = b.server_editor_id AND b.client_id = " );
+	befehl->append( client );
+	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;
+}
+
+// Reference Counting
+MSDatenbank *MSDatenbank::getThis()
+{
+	ref++;
+	return this;
+}
+
+MSDatenbank *MSDatenbank::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 82 - 0
MainServer/Datenbank.h

@@ -0,0 +1,82 @@
+#ifndef Datenbank_H
+#define Datenbank_H
+
+#include <sql.h>
+#include <Text.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+using namespace sql;
+
+namespace Admin_Recht
+{
+	const int MSStarten = 0x00000001;
+	const int MSBeenden = 0x00000002;
+}
+
+class MSDatenbank
+{
+private:
+	Datenbank *datenbank;
+	CRITICAL_SECTION ths;
+	int ref;
+
+public:
+	// Konstruktor
+	MSDatenbank( InitDatei *zDat );
+	// Detruktor
+	~MSDatenbank();
+	// nicht constant
+	void lock();
+	void unlock();
+	int istAdministrator( const char *name, const char *passwort );
+	bool adminHatRecht( int id, int recht );
+	unsigned int getNextClientId();
+	Text *getKlientKey( int cId );
+	bool proveRegisteredClient( unsigned int num );
+	int *unregisterClient( unsigned int num );
+	int suchPatchServer( unsigned int client );
+	unsigned char *getPatchServerPortIp( int num );
+	int suchRegisterServer( unsigned int client );
+	unsigned char *getRegisterServerPortIp( int num );
+	int suchLoginServer( unsigned int client );
+	unsigned char *getLoginServerPortIp( int num );
+	int suchInformationServer( unsigned int client );
+	unsigned char *getInformationServerPortIp( int num );
+	int suchChatServer( unsigned int client );
+	unsigned char *getChatServerPortIp( int num );
+	int suchAnmeldungServer( unsigned int client );
+	unsigned char *getAnmeldungServerPortIp( int num );
+	int suchErhaltungServer( unsigned int client );
+	unsigned char *getErhaltungServerPortIp( int num );
+	int suchShopServer( unsigned int client );
+	unsigned char *getShopServerPortIp( int num );
+	int suchNewsServer( unsigned int client );
+	unsigned char *getNewsServerPortIp( int num );
+	int logoutKlient( int klientId, Array< int > *ret );
+	bool getSpielServerPortIp( int spielErstelltId, unsigned short *port, Text *ip );
+	int getSpielerAusGruppe( int gruppeId, Array< int > *accountId );
+	int kickSpielerAusGruppe( int gruppeId, int accountId );
+	bool getChatServerPortIp( int accountId, unsigned short *port, Text *ip );
+	int getGruppeAdmin( int gruppeId );
+	int getSpielerAusChatroom( int chatroomId, Array< int > *accountId );
+	int getChatroomAdmin( int chatroomId );
+	int clientistEingeloggt( int clientId );
+	bool getPatchServer( int client, Text *ip, int *port );
+	bool getRegisterServer( int client, Text *ip, int *port );
+	bool getLoginServer( int client, Text *ip, int *port );
+	bool getInformationServer( int client, Text *ip, int *port );
+	bool getChatServer( int client, Text *ip, int *port );
+	bool getAnmeldungServer( int client, Text *ip, int *port );
+	bool getSpielServer( int client, Text *ip, int *port );
+	bool getShopServer( int client, Text *ip, int *port );
+	bool getNewsServer( int client, Text *ip, int *port );
+    bool getHistorieServer( int client, Text *ip, int *port );
+    bool getKartenServer( int client, Text *ip, int *port );
+    bool getEditorServer( int client, Text *ip, int *port );
+	// Reference Counting
+	MSDatenbank *getThis();
+	MSDatenbank *release();
+};
+
+#endif

+ 1520 - 0
MainServer/MainServer.cpp

@@ -0,0 +1,1520 @@
+#include "MainServer.h"
+#include "Datenbank.h"
+#include <Text.h>
+#include <iostream>
+#include <Klient.h>
+#include <Globals.h>
+
+// Inhalt der MainServer Klasse aus MainServer.h
+// Konstruktor 
+MainServer::MainServer( InitDatei *zDat )
+: Thread()
+{
+	Network::Start( 100 );
+	std::cout << "MS: Verbindung mit Datenbank wird hergestellt...\n";
+	db = new MSDatenbank( zDat );
+	clients = 0;
+	empfangen = 0;
+	gesendet = 0;
+	dat = zDat->getThis();
+	if( !zDat->wertExistiert( "MSPort" ) )
+		zDat->addWert( "MSPort", "4253" );
+	if( !zDat->wertExistiert( "MSAPort" ) )
+		zDat->addWert( "MSAPort", "4252" );
+	server = new Server();
+	aServer = new Server();
+	std::cout << "MS: Starten des Admin Servers...\n";
+	if( !aServer->verbinde( (unsigned short)TextZuInt( zDat->zWert( "MSAPort" )->getText(), 10 ), 10 ) )
+	{
+		std::cout << "MS: Der Admin Server konnte nicht gestartet werden. Das Programm wird beendet.\n";
+		exit( 1 );
+	}
+	end = 0;
+	InitializeCriticalSection( &cs );
+	ref = 1;
+    if( zDat->wertExistiert( "Aktiv" ) && zDat->zWert( "Aktiv" )->istGleich( "TRUE" ) )
+        serverStarten();
+}
+
+// Destruktor 
+MainServer::~MainServer()
+{
+	ende();
+	server->trenne();
+	server->release();
+	aServer->trenne();
+	aServer->release();
+	dat->release();
+	db->release();
+	Network::Exit();
+	DeleteCriticalSection( &cs );
+}
+
+// nicht constant 
+void MainServer::runn()
+{
+	while( !end )
+	{
+		SKlient *klient;
+		klient = aServer->getKlient();
+		if( end && klient )
+		{
+			klient->trenne();
+			klient = klient->release();
+			Sleep( 1000 );
+			return;
+		}
+		if( !klient )
+			return;
+		MSAKlient *clHandle = new MSAKlient( klient, getThis() );
+		clHandle->start();
+	}
+}
+
+void MainServer::thread()
+{
+	while( 1 )
+	{
+		SKlient *klient;
+		klient = server->getKlient();
+		if( !klient )
+			break;
+		Framework::getThreadRegister()->cleanUpClosedThreads();
+		MSKlient *clHandle = new MSKlient( klient, getThis() );
+		clHandle->start();
+		clients++;
+	}
+	run = 0;
+}
+
+void MainServer::close()
+{
+	server->trenne();
+#ifdef WIN32
+	warteAufThread( 1000 );
+#endif
+	ende();
+	run = 0;
+	end = 1;
+	Klient *klient = new Klient();
+	klient->verbinde( aServer->getPort(), "127.0.0.1" );
+	Sleep( 500 );
+	aServer->trenne();
+	klient->release();
+}
+
+bool MainServer::serverStarten()
+{
+	if( run )
+		return 1;
+	bool ret = server->verbinde( (unsigned short)TextZuInt( dat->zWert( "MSPort" )->getText(), 10 ), 10 );
+	start();
+	return ret;
+}
+
+void MainServer::serverBeenden()
+{
+	if( !run )
+		return;
+	server->trenne();
+#ifdef WIN32
+	warteAufThread( 1000 );
+#endif
+	ende();
+	server->release();
+	server = new Server();
+	run = 0;
+}
+
+void MainServer::addGesendet( int bytes )
+{
+	gesendet += bytes;
+}
+
+void MainServer::addEmpfangen( int bytes )
+{
+	empfangen += empfangen;
+}
+
+void MainServer::clientTrennung()
+{
+	clients--;
+}
+
+// constant 
+Server *MainServer::zServer() const
+{
+	return server;
+}
+
+MSDatenbank *MainServer::zDB() const
+{
+	return db;
+}
+
+bool MainServer::hatClients() const
+{
+	return clients > 0;
+}
+
+// Reference Counting
+MainServer *MainServer::getThis()
+{
+	EnterCriticalSection( &cs );
+	ref++;
+	LeaveCriticalSection( &cs );
+	return this;
+}
+
+MainServer *MainServer::release()
+{
+	EnterCriticalSection( &cs );
+	ref--;
+	LeaveCriticalSection( &cs );
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der MSKlient Klasse aus MainServer.h
+// Konstruktor 
+MSAKlient::MSAKlient( SKlient *klient, MainServer *ms )
+: Thread()
+{
+	this->klient = klient;
+	unsigned char key[ 20 ] = { 103, 112, 161, 152, 241, 81, 192, 29, 85, 160, 151, 68, 120, 164, 145, 208, 65, 241, 234, 219 };
+	klient->setSendeKey( (char*)key, 20 );
+	klient->setEmpfangKey( (char*)key, 20 );
+	name = new Text( "" );
+	passwort = new Text( "" );
+	adminId = 0;
+	this->ms = ms;
+}
+
+// Destruktor 
+MSAKlient::~MSAKlient()
+{
+	klient->trenne();
+	klient->release();
+	ms->release();
+	name->release();
+	passwort->release();
+}
+
+// nicht constant 
+void MSAKlient::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 = ms->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( ms->zDB()->adminHatRecht( adminId, Admin_Recht::MSStarten ) )
+					{
+						if( !ms->serverStarten() )
+							errorZuKlient( "Beim starten des Servers ist ein Fehler aufgetreten." );
+						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( ms->zDB()->adminHatRecht( adminId, Admin_Recht::MSBeenden ) )
+					{
+						ms->serverBeenden();
+						klient->sendeEncrypted( "\1", 1 );
+					}
+					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( ms->isRunning() )
+					{
+						if( ms->zDB()->adminHatRecht( adminId, Admin_Recht::MSBeenden ) )
+						{
+							ms->serverBeenden();
+							ok = 1;
+						}
+						else
+							errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+					}
+					else
+						ok = 1;
+					if( ok && ms->hatClients() )
+					{
+						errorZuKlient( "Es sind noch Klients Online. Bitte versuche es später erneut." );
+						break;
+					}
+					if( ok )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						std::cout << "MS: Der Server wird von Benutzer " << adminId << " heruntergefahren.\n";
+						ms->close();
+						br = 1;
+					}
+				}
+				break;
+			case 7: // Progtamm abstürzen
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					bool ok = 0;
+					if( ms->isRunning() )
+					{
+						if( ms->zDB()->adminHatRecht( adminId, Admin_Recht::MSBeenden ) )
+						{
+							ms->serverBeenden();
+							ok = 1;
+						}
+						else
+							errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+					}
+					else
+						ok = 1;
+					if( ok )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						std::cout << "MS: Der Server wurde von Benutzer " << adminId << " terminiert.\n";
+						ms->close();
+						br = 1;
+					}
+				}
+				break;
+			case 8: // Status Frage
+				if( 1 )
+				{
+					klient->sendeEncrypted( "\1", 1 );
+					char status = (int)ms->isRunning();
+					klient->sendeEncrypted( &status, 1 );
+				}
+				break;
+			default:
+				errorZuKlient( "Unbekannte Nachricht!" );
+				break;
+			}
+			if( br )
+				break;
+			ms->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			ms->addGesendet( klient->getUploadBytes( 1 ) );
+		}
+	}
+	ms->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	ms->addGesendet( klient->getUploadBytes( 1 ) );
+	delete this;
+}
+
+void MSAKlient::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 MSKlient Klasse aus MainServer.h
+// Konstruktor 
+MSKlient::MSKlient( SKlient *klient, MainServer *ms )
+: Thread()
+{
+	this->klient = klient;
+	unsigned char key[ 20 ] = { 199, 164, 172, 55, 246, 16, 155, 8, 151, 176, 250, 181, 227, 133, 30, 41, 200, 26, 7, 151 };
+	klient->setSendeKey( (char*)key, 20 );
+	klient->setEmpfangKey( (char*)key, 20 );
+	klientNummer = 0;
+	this->ms = ms;
+	encrypted = 0;
+}
+
+// Destruktor 
+MSKlient::~MSKlient()
+{
+	ms->clientTrennung();
+	ms->release();
+	klient->release();
+}
+
+// nicht constant 
+void MSKlient::thread()
+{
+	while( 1 )
+	{
+		char c = 0;
+		if( ( !encrypted && !klient->getNachricht( &c, 1 ) ) || ( encrypted && !klient->getNachrichtEncrypted( &c, 1 ) ) )
+			break;
+		else
+		{
+			bool br = 0;
+			switch( c )
+			{
+			case 0:
+				encrypted = 1;
+				break;
+			case 1: // Client Identifikation
+				if( 1 )
+				{
+					if( encrypted )
+					    klient->getNachrichtEncrypted( (char*)&klientNummer, 4 );
+					else
+						klient->getNachricht( (char*)&klientNummer, 4 );
+					bool ret1 = 0;
+					if( !klientNummer )
+					{
+						klientNummer = ms->zDB()->getNextClientId();
+						if( encrypted )
+						{
+							Text *key = ms->zDB()->getKlientKey( klientNummer );
+							if( key )
+							{
+								klient->sendeEncrypted( "\1", 1 );
+								klient->sendeEncrypted( (char*)&klientNummer, 4 );
+								char len = (char)key->getLength();
+								klient->sendeEncrypted( &len, 1 );
+								if( len )
+									klient->sendeEncrypted( key->getText(), len );
+								klient->setEmpfangKey( *key, len );
+								klient->setSendeKey( *key, len );
+								key->release();
+							}
+							else
+								errorZuKlient( "Es konnte kein Schlüssel ermittelt werden." );
+						}
+						else
+						{
+							klient->sende( "\1", 1 );
+							klient->sende( (char*)&klientNummer, 4 );
+						}
+						ret1 = 1;
+					}
+					if( !ms->zDB()->proveRegisteredClient( klientNummer ) )
+						errorZuKlient( "Deine Client Nummer ist nicht aktiv!\0" );
+					else if( !ret1 )
+					{
+						if( encrypted )
+						{
+							Text *key = ms->zDB()->getKlientKey( klientNummer );
+							if( !key )
+								errorZuKlient( "Es konnte kein Schlüssel ermittelt werden." );
+							else
+							{
+								klient->sendeEncrypted( "\1", 1 );
+								klient->setEmpfangKey( *key, key->getLength() );
+								klient->setSendeKey( *key, key->getLength() );
+								key->release();
+							}
+						}
+						else
+						    klient->sende( "\1", 1 );
+					}
+				}
+				break;
+			case 3: // Verbindungsende
+				br = 1;
+				if( encrypted )
+					klient->sendeEncrypted( "\1", 1 );
+				else
+					klient->sende( "\1", 1 );
+				break;
+			case 6: // frage nach Server
+				if( 1 )
+				{
+					char serverTyp = 0;
+					if( encrypted )
+						klient->getNachrichtEncrypted( &serverTyp, 1 );
+					else
+						klient->getNachricht( &serverTyp, 1 );
+					switch( serverTyp )
+					{
+					case 1: // Register Server
+						if( klientNummer )
+						{
+							int sNum = ms->zDB()->suchRegisterServer( klientNummer );
+							if( sNum )
+							{
+								unsigned char *msg = ms->zDB()->getRegisterServerPortIp( sNum );
+								if( msg )
+								{
+									if( encrypted )
+									{
+										klient->sendeEncrypted( "\2", 1 );
+										klient->sendeEncrypted( (char*)msg, 6 );
+									}
+									else
+									{
+										klient->sende( "\2", 1 );
+										klient->sende( (char*)msg, 6 );
+									}
+								}
+								else
+									errorZuKlient( "Aufgrund eines unerwarteten Fehlers konnte dir kein\nRegistrierungsserver zugewiesen werden!\0" );
+								delete[]msg;
+							}
+							else
+								errorZuKlient( "Der Server ist derzeit ausgelastet!\0" );
+						}
+						else
+							errorZuKlient( "Du besitzt noch keine Client Nummer!\0" );
+						break;
+					case 2: // Patch Server
+						if( klientNummer )
+						{
+							int sNum = ms->zDB()->suchPatchServer( klientNummer );
+							if( sNum )
+							{
+								unsigned char *msg = ms->zDB()->getPatchServerPortIp( sNum );
+								if( msg )
+								{
+									if( encrypted )
+									{
+										klient->sendeEncrypted( "\2", 1 );
+										klient->sendeEncrypted( (char*)msg, 6 );
+									}
+									else
+									{
+										klient->sende( "\2", 1 );
+										klient->sende( (char*)msg, 6 );
+									}
+								}
+								else
+									errorZuKlient( "Aufgrund eines unerwarteten Fehlers konnte dir kein\nPatchserver zugewiesen werden!\0" );
+								delete[]msg;
+							}
+							else
+								errorZuKlient( "Der Server ist derzeit ausgelastet!\0" );
+						}
+						else
+							errorZuKlient( "Du besitzt noch keine Client Nummer!\0" );
+						break;
+					case 3: // Login Server
+						if( klientNummer )
+						{
+							int sNum = ms->zDB()->suchLoginServer( klientNummer );
+							if( sNum )
+							{
+								unsigned char *msg = ms->zDB()->getLoginServerPortIp( sNum );
+								if( msg )
+								{
+									if( encrypted )
+									{
+										klient->sendeEncrypted( "\2", 1 );
+										klient->sendeEncrypted( (char*)msg, 6 );
+									}
+									else
+									{
+										klient->sende( "\2", 1 );
+										klient->sende( (char*)msg, 6 );
+									}
+								}
+								else
+									errorZuKlient( "Aufgrund eines unerwarteten Fehlers konnte dir kein\nLoginserver zugewiesen werden!\0" );
+								delete[]msg;
+							}
+							else
+								errorZuKlient( "Der Server ist derzeit ausgelastet!\0" );
+						}
+						else
+							errorZuKlient( "Du besitzt noch keine Client Nummer!\0" );
+						break;
+					case 4: // Informations Server
+						if( klientNummer )
+						{
+							int sNum = ms->zDB()->suchInformationServer( klientNummer );
+							if( sNum )
+							{
+								unsigned char *msg = ms->zDB()->getInformationServerPortIp( sNum );
+								if( msg )
+								{
+									if( encrypted )
+									{
+										klient->sendeEncrypted( "\2", 1 );
+										klient->sendeEncrypted( (char*)msg, 6 );
+									}
+									else
+									{
+										klient->sende( "\2", 1 );
+										klient->sende( (char*)msg, 6 );
+									}
+								}
+								else
+									errorZuKlient( "Aufgrund eines unerwarteten Fehlers konnte dir kein\nInformationserver zugewiesen werden!\0" );
+								delete[]msg;
+							}
+							else
+								errorZuKlient( "Der Server ist derzeit ausgelastet!\0" );
+						}
+						else
+							errorZuKlient( "Du besitzt noch keine Client Nummer!\0" );
+						break;
+					case 5: // Chat Server
+						if( klientNummer )
+						{
+							int sNum = ms->zDB()->suchChatServer( klientNummer );
+							if( sNum )
+							{
+								unsigned char *msg = ms->zDB()->getChatServerPortIp( sNum );
+								if( msg )
+								{
+									if( encrypted )
+									{
+										klient->sendeEncrypted( "\2", 1 );
+										klient->sendeEncrypted( (char*)msg, 6 );
+									}
+									else
+									{
+										klient->sende( "\2", 1 );
+										klient->sende( (char*)msg, 6 );
+									}
+								}
+								else
+									errorZuKlient( "Aufgrund eines unerwarteten Fehlers konnte dir kein\nChatserver zugewiesen werden!\0" );
+								delete[]msg;
+							}
+							else
+								errorZuKlient( "Der Server ist derzeit ausgelastet!\0" );
+						}
+						else
+							errorZuKlient( "Du besitzt noch keine Client Nummer!\0" );
+						break;
+					case 6: // Anmeldung Server
+						if( klientNummer )
+						{
+							int sNum = ms->zDB()->suchAnmeldungServer( klientNummer );
+							if( sNum )
+							{
+								unsigned char *msg = ms->zDB()->getAnmeldungServerPortIp( sNum );
+								if( msg )
+								{
+									if( encrypted )
+									{
+										klient->sendeEncrypted( "\2", 1 );
+										klient->sendeEncrypted( (char*)msg, 6 );
+									}
+									else
+									{
+										klient->sende( "\2", 1 );
+										klient->sende( (char*)msg, 6 );
+									}
+								}
+								else
+									errorZuKlient( "Aufgrund eines unerwarteten Fehlers konnte dir kein\nAnmeldungserver zugewiesen werden!\0" );
+								delete[]msg;
+							}
+							else
+								errorZuKlient( "Der Server ist derzeit ausgelastet!\0" );
+						}
+						else
+							errorZuKlient( "Du besitzt noch keine Client Nummer!\0" );
+						break;
+					case 7: // Shop Server
+						if( klientNummer )
+						{
+							int sNum = ms->zDB()->suchShopServer( klientNummer );
+							if( sNum )
+							{
+								unsigned char *msg = ms->zDB()->getShopServerPortIp( sNum );
+								if( msg )
+								{
+									if( encrypted )
+									{
+										klient->sendeEncrypted( "\2", 1 );
+										klient->sendeEncrypted( (char*)msg, 6 );
+									}
+									else
+									{
+										klient->sende( "\2", 1 );
+										klient->sende( (char*)msg, 6 );
+									}
+								}
+								else
+									errorZuKlient( "Aufgrund eines unerwarteten Fehlers konnte dir kein\nShopserver zugewiesen werden!\0" );
+								delete[]msg;
+							}
+							else
+								errorZuKlient( "Der Server ist derzeit ausgelastet!\0" );
+						}
+						else
+							errorZuKlient( "Du besitzt noch keine Client Nummer!\0" );
+						break;
+					case 8: // Erhaltung Server
+						if( klientNummer )
+						{
+							int sNum = ms->zDB()->suchErhaltungServer( klientNummer );
+							if( sNum )
+							{
+								unsigned char *msg = ms->zDB()->getErhaltungServerPortIp( sNum );
+								if( msg )
+								{
+									if( encrypted )
+									{
+										klient->sendeEncrypted( "\2", 1 );
+										klient->sendeEncrypted( (char*)msg, 6 );
+									}
+									else
+									{
+										klient->sende( "\2", 1 );
+										klient->sende( (char*)msg, 6 );
+									}
+								}
+								else
+									errorZuKlient( "Aufgrund eines unerwarteten Fehlers konnte dir kein\nPatchserver zugewiesen werden!\0" );
+								delete[]msg;
+							}
+							else
+								errorZuKlient( "Der Server ist derzeit ausgelastet!\0" );
+						}
+						else
+							errorZuKlient( "Du besitzt noch keine Client Nummer!\0" );
+						break;
+					case 9: // News Server
+						if( klientNummer )
+						{
+							int sNum = ms->zDB()->suchNewsServer( klientNummer );
+							if( sNum )
+							{
+								unsigned char *msg = ms->zDB()->getNewsServerPortIp( sNum );
+								if( msg )
+								{
+									if( encrypted )
+									{
+										klient->sendeEncrypted( "\2", 1 );
+										klient->sendeEncrypted( (char*)msg, 6 );
+									}
+									else
+									{
+										klient->sende( "\2", 1 );
+										klient->sende( (char*)msg, 6 );
+									}
+								}
+								else
+									errorZuKlient( "Aufgrund eines unerwarteten Fehlers konnte dir kein\nNewsserver zugewiesen werden!\0" );
+								delete[]msg;
+							}
+							else
+								errorZuKlient( "Der Server ist derzeit ausgelastet!\0" );
+						}
+						else
+							errorZuKlient( "Du besitzt noch keine Client Nummer!\0" );
+						break;
+					default:
+						errorZuKlient( "Die Art des Servers ist nicht bekannt!\0" );
+						break;
+					}
+				}
+				break;
+			case 7: // client unregistrierung
+				if( klientNummer )
+				{
+					int accountId = ms->zDB()->clientistEingeloggt( klientNummer );
+					if( accountId )
+					{
+						Array< int > *ret = new Array< int >();
+						int anzahl = ms->zDB()->logoutKlient( klientNummer, ret );
+						if( anzahl > 0 )
+						{
+							int jetzt = 0;
+							int chAnz = ret->get( jetzt );
+							jetzt++;
+							for( int i = 0; i < chAnz; i++ )
+							{
+								int chatroomId = ret->get( jetzt );
+								jetzt++;
+								if( chatroomId )
+								{
+									MSGWeiterleitung *weiter = new MSGWeiterleitung( ms->getThis() );
+									weiter->spielerLeavesChatroom( chatroomId, accountId );
+									weiter->release();
+									if( ret->get( jetzt ) )
+									{
+										MSGWeiterleitung *weiter = new MSGWeiterleitung( ms->getThis() );
+										weiter->setChatroomAdmin( chatroomId, ms->zDB()->getChatroomAdmin( chatroomId ) );
+										weiter->release();
+									}
+									jetzt++;
+								}
+							}
+							if( ret->get( jetzt ) == 1 )
+							{
+								jetzt++;
+								MSGWeiterleitung *weiter = new MSGWeiterleitung( ms->getThis() );
+								weiter->spielErstelltAbbrechen( ret->get( jetzt ) );
+								weiter->release();
+							}
+							jetzt++;
+							if( ret->get( jetzt ) == 1 )
+							{
+								jetzt++;
+								int gruppeId = ret->get( jetzt );
+								MSGWeiterleitung *weiter = new MSGWeiterleitung( ms->getThis() );
+								weiter->spielerLeavesGruppe( gruppeId, accountId );
+								weiter->release();
+								jetzt++;
+								if( ret->get( jetzt ) )
+								{
+									MSGWeiterleitung *weiter = new MSGWeiterleitung( ms->getThis() );
+									weiter->setGruppeAdmin( gruppeId, ms->zDB()->getGruppeAdmin( gruppeId ) );
+									weiter->release();
+								}
+							}
+							else if( ret->get( jetzt ) == 2 )
+							{
+								jetzt++;
+								int gruppeId = ret->get( jetzt );
+								MSGWeiterleitung *weiter = new MSGWeiterleitung( ms->getThis() );
+								weiter->kickSpielerAusGruppe( gruppeId );
+								weiter->release();
+							}
+						}
+					}
+					MSGWeiterleitung *weiter = new MSGWeiterleitung( ms->getThis() );
+					weiter->patchServerKlientAbsturz( klientNummer );
+					weiter->registerServerKlientAbsturz( klientNummer );
+					weiter->loginServerKlientAbsturz( klientNummer );
+					weiter->informationServerKlientAbsturz( klientNummer );
+					weiter->chatServerKlientAbsturz( klientNummer );
+					weiter->anmeldungServerKlientAbsturz( klientNummer );
+					weiter->spielServerKlientAbsturz( klientNummer );
+					weiter->shopServerKlientAbsturz( klientNummer );
+					weiter->newsServerKlientAbsturz( klientNummer );
+                    weiter->historieServerKlientAbsturz( klientNummer );
+                    weiter->kartenServerKlientAbsturz( klientNummer );
+                    weiter->editorServerKlientAbsturz( klientNummer );
+					weiter->release();
+					int *treffer = ms->zDB()->unregisterClient( klientNummer );
+					if( !treffer[ 12 ] )
+						errorZuKlient( "Du bist nicht registriert!\0" );
+					else
+					{
+						if( encrypted )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						    klient->sende( "\1", 1 );
+					}
+					delete[]treffer;
+				}
+				else
+					errorZuKlient( "Du besitzt noch keine Client Nummer!\0" );
+				break;
+			default:
+				errorZuKlient( "Unbekannte Nachricht!\0" );
+				break;
+			}
+			if( br )
+				break;
+			ms->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			ms->addGesendet( klient->getUploadBytes( 1 ) );
+		}
+	}
+	ms->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	ms->addGesendet( klient->getUploadBytes( 1 ) );
+	delete this;
+}
+
+void MSKlient::errorZuKlient( const char *nachricht ) const // sendet eine Fehlernachricht zum Klient
+{
+	if( encrypted )
+	{
+		klient->sendeEncrypted( "\3", 1 );
+		char len = (char)textLength( nachricht );
+		klient->sendeEncrypted( &len, 1 );
+		klient->sendeEncrypted( nachricht, len );
+	}
+	else
+	{
+		klient->sende( "\3", 1 );
+		char len = (char)textLength( nachricht );
+		klient->sende( &len, 1 );
+		klient->sende( nachricht, len );
+	}
+}
+
+
+// Inhalt der MSGWeiterleitung Klasse aus LoginServer.h
+// Konstruktor
+MSGWeiterleitung::MSGWeiterleitung( MainServer *ms )
+{
+	this->ms = ms;
+	ref = 1;
+}
+
+// Destruktor
+MSGWeiterleitung::~MSGWeiterleitung()
+{
+	ms->release();
+}
+
+// nicht constant
+bool MSGWeiterleitung::patchServerKlientAbsturz( int klientId )
+{
+	Text *ip = new Text();
+	int port = 0;
+	if( !ms->zDB()->getPatchServer( klientId, ip, &port ) )
+	{
+		ip->release();
+		return 0;
+	}
+	Klient *k = new Klient();
+	unsigned char key[ 20 ] = { 102, 139, 140, 143, 52, 52, 194, 167, 97, 106, 23, 72, 170, 121, 213, 178, 28, 28, 124, 185 };
+	k->setSendeKey( (char*)key, 20 );
+	k->setEmpfangKey( (char*)key, 20 );
+	k->verbinde( (unsigned short)port, ip->getText() );
+	ip->release();
+	char ret = 0;
+	k->sende( "\0", 1 ); // Verkeyung aktivieren
+	k->sendeEncrypted( "\2\2", 2 );
+	k->sendeEncrypted( (char*)&klientId, 4 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	bool erf = ret == 1;
+	k->sendeEncrypted( "\3", 1 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+	ms->addGesendet( k->getUploadBytes( 1 ) );
+	k->trenne();
+	k->release();
+	return erf;
+}
+
+bool MSGWeiterleitung::registerServerKlientAbsturz( int klientId )
+{
+	Text *ip = new Text();
+	int port = 0;
+	if( !ms->zDB()->getRegisterServer( klientId, ip, &port ) )
+	{
+		ip->release();
+		return 0;
+	}
+	Klient *k = new Klient();
+	unsigned char key[ 20 ] = { 186, 186, 179, 126, 216, 207, 123, 154, 168, 149, 51, 221, 6, 193, 160, 141, 164, 126, 44, 242 };
+	k->setSendeKey( (char*)key, 20 );
+	k->setEmpfangKey( (char*)key, 20 );
+	k->verbinde( (unsigned short)port, ip->getText() );
+	ip->release();
+	char ret = 0;
+	k->sendeEncrypted( "\2\2", 2 );
+	k->sendeEncrypted( (char*)&klientId, 4 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	bool erf = ret == 1;
+	k->sendeEncrypted( "\3", 1 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+	ms->addGesendet( k->getUploadBytes( 1 ) );
+	k->trenne();
+	k->release();
+	return erf;
+}
+
+bool MSGWeiterleitung::loginServerKlientAbsturz( int klientId )
+{
+	Text *ip = new Text();
+	int port = 0;
+	if( !ms->zDB()->getLoginServer( klientId, ip, &port ) )
+	{
+		ip->release();
+		return 0;
+	}
+	Klient *k = new Klient();
+	unsigned char key[ 20 ] = { 143, 166, 245, 235, 76, 75, 116, 80, 26, 178, 142, 176, 109, 53, 106, 222, 223, 55, 139, 111 };
+	k->setSendeKey( (char*)key, 20 );
+	k->setEmpfangKey( (char*)key, 20 );
+	k->verbinde( (unsigned short)port, ip->getText() );
+	ip->release();
+	char ret = 0;
+	k->sendeEncrypted( "\2\2", 2 );
+	k->sendeEncrypted( (char*)&klientId, 4 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	bool erf = ret == 1;
+	k->sendeEncrypted( "\3", 1 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+	ms->addGesendet( k->getUploadBytes( 1 ) );
+	k->trenne();
+	k->release();
+	return erf;
+}
+
+bool MSGWeiterleitung::informationServerKlientAbsturz( int klientId )
+{
+	Text *ip = new Text();
+	int port = 0;
+	if( !ms->zDB()->getInformationServer( klientId, ip, &port ) )
+	{
+		ip->release();
+		return 0;
+	}
+	Klient *k = new Klient();
+	unsigned char key[ 20 ] = { 231, 246, 125, 32, 88, 172, 229, 223, 246, 138, 74, 64, 142, 245, 217, 218, 162, 62, 103, 50 };
+	k->setSendeKey( (char*)key, 20 );
+	k->setEmpfangKey( (char*)key, 20 );
+	k->verbinde( (unsigned short)port, ip->getText() );
+	ip->release();
+	char ret = 0;
+	k->sendeEncrypted( "\2\2", 2 );
+	k->sendeEncrypted( (char*)&klientId, 4 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	bool erf = ret == 1;
+	k->sendeEncrypted( "\3", 1 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+	ms->addGesendet( k->getUploadBytes( 1 ) );
+	k->trenne();
+	k->release();
+	return erf;
+}
+
+bool MSGWeiterleitung::chatServerKlientAbsturz( int klientId )
+{
+	Text *ip = new Text();
+	int port = 0;
+	if( !ms->zDB()->getChatServer( klientId, ip, &port ) )
+	{
+		ip->release();
+		return 0;
+	}
+	Klient *k = 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 };
+	k->setSendeKey( (char*)key, 20 );
+	k->setEmpfangKey( (char*)key, 20 );
+	k->verbinde( (unsigned short)port, ip->getText() );
+	ip->release();
+	char ret = 0;
+	k->sendeEncrypted( "\2\2", 2 );
+	k->sendeEncrypted( (char*)&klientId, 4 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	bool erf = ret == 1;
+	k->sendeEncrypted( "\3", 1 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+	ms->addGesendet( k->getUploadBytes( 1 ) );
+	k->trenne();
+	k->release();
+	return erf;
+}
+
+bool MSGWeiterleitung::anmeldungServerKlientAbsturz( int klientId )
+{
+	Text *ip = new Text();
+	int port = 0;
+	if( !ms->zDB()->getAnmeldungServer( klientId, ip, &port ) )
+	{
+		ip->release();
+		return 0;
+	}
+	Klient *k = new Klient();
+	unsigned char key[ 20 ] = { 158, 10, 37, 155, 117, 58, 28, 197, 132, 76, 252, 83, 84, 222, 11, 125, 240, 218, 25, 201 };
+	k->setSendeKey( (char*)key, 20 );
+	k->setEmpfangKey( (char*)key, 20 );
+	k->verbinde( (unsigned short)port, ip->getText() );
+	ip->release();
+	char ret = 0;
+	k->sendeEncrypted( "\2\2", 2 );
+	k->sendeEncrypted( (char*)&klientId, 4 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	bool erf = ret == 1;
+	k->sendeEncrypted( "\3", 1 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+	ms->addGesendet( k->getUploadBytes( 1 ) );
+	k->trenne();
+	k->release();
+	return erf;
+}
+
+bool MSGWeiterleitung::spielServerKlientAbsturz( int klientId )
+{
+	Text *ip = new Text();
+	int port = 0;
+	if( !ms->zDB()->getSpielServer( klientId, ip, &port ) )
+	{
+		ip->release();
+		return 0;
+	}
+	Klient *k = new Klient();
+	unsigned char key[ 20 ] = { 253, 234, 211, 132, 121, 230, 95, 145, 201, 13, 43, 77, 153, 223, 253, 69, 234, 43, 52, 99 };
+	k->setSendeKey( (char*)key, 20 );
+	k->setEmpfangKey( (char*)key, 20 );
+	k->verbinde( (unsigned short)port, ip->getText() );
+	ip->release();
+	char ret = 0;
+	k->sendeEncrypted( "\2\2", 2 );
+	k->sendeEncrypted( (char*)&klientId, 4 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	bool erf = ret == 1;
+	k->sendeEncrypted( "\3", 1 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+	ms->addGesendet( k->getUploadBytes( 1 ) );
+	k->trenne();
+	k->release();
+	return erf;
+}
+
+bool MSGWeiterleitung::shopServerKlientAbsturz( int klientId )
+{
+	Text *ip = new Text();
+	int port = 0;
+	if( !ms->zDB()->getShopServer( klientId, ip, &port ) )
+	{
+		ip->release();
+		return 0;
+	}
+	Klient *k = new Klient();
+	unsigned char key[ 20 ] = { 218, 226, 231, 216, 68, 63, 132, 155, 49, 235, 239, 0, 19, 23, 116, 244, 235, 21, 189, 53 };
+	k->setSendeKey( (char*)key, 20 );
+	k->setEmpfangKey( (char*)key, 20 );
+	k->verbinde( (unsigned short)port, ip->getText() );
+	ip->release();
+	char ret = 0;
+	k->sendeEncrypted( "\2\2", 2 );
+	k->sendeEncrypted( (char*)&klientId, 4 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	bool erf = ret == 1;
+	k->sendeEncrypted( "\3", 1 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+	ms->addGesendet( k->getUploadBytes( 1 ) );
+	k->trenne();
+	k->release();
+	return erf;
+}
+
+bool MSGWeiterleitung::newsServerKlientAbsturz( int klientId )
+{
+	Text *ip = new Text();
+	int port = 0;
+	if( !ms->zDB()->getNewsServer( klientId, ip, &port ) )
+	{
+		ip->release();
+		return 0;
+	}
+	Klient *k = new Klient();
+	unsigned char key[ 20 ] = { 4, 150, 243, 145, 204, 71, 253, 88, 4, 51, 189, 207, 189, 248, 231, 40, 106, 7, 182, 5 };
+	k->setSendeKey( (char*)key, 20 );
+	k->setEmpfangKey( (char*)key, 20 );
+	k->verbinde( (unsigned short)port, ip->getText() );
+	ip->release();
+	char ret = 0;
+	k->sendeEncrypted( "\2\2", 2 );
+	k->sendeEncrypted( (char*)&klientId, 4 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	bool erf = ret == 1;
+	k->sendeEncrypted( "\3", 1 );
+	k->getNachrichtEncrypted( &ret, 1 );
+	ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+	ms->addGesendet( k->getUploadBytes( 1 ) );
+	k->trenne();
+	k->release();
+	return erf;
+}
+
+bool MSGWeiterleitung::historieServerKlientAbsturz( int klientId )
+{
+    Text *ip = new Text();
+    int port = 0;
+    if( !ms->zDB()->getHistorieServer( klientId, ip, &port ) )
+    {
+        ip->release();
+        return 0;
+    }
+    Klient *k = new Klient();
+    unsigned char key[ 20 ] = { 207, 30, 72, 46, 30, 50, 56, 213, 82, 107, 14, 201, 149, 58, 110, 138, 228, 241, 52, 54 };
+    k->setSendeKey( (char*)key, 20 );
+    k->setEmpfangKey( (char*)key, 20 );
+    k->verbinde( (unsigned short)port, ip->getText() );
+    ip->release();
+    char ret = 0;
+    k->sendeEncrypted( "\2\2", 2 );
+    k->sendeEncrypted( (char*)&klientId, 4 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    bool erf = ret == 1;
+    k->sendeEncrypted( "\3", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+    ms->addGesendet( k->getUploadBytes( 1 ) );
+    k->trenne();
+    k->release();
+    return erf;
+}
+
+bool MSGWeiterleitung::kartenServerKlientAbsturz( int klientId )
+{
+    Text *ip = new Text();
+    int port = 0;
+    if( !ms->zDB()->getKartenServer( klientId, ip, &port ) )
+    {
+        ip->release();
+        return 0;
+    }
+    Klient *k = new Klient();
+    unsigned char key[ 20 ] = { 24, 15, 53, 87, 38, 73, 154, 38, 246, 90, 39, 133, 11, 199, 22, 80, 26, 132, 95, 54 };
+    k->setSendeKey( (char*)key, 20 );
+    k->setEmpfangKey( (char*)key, 20 );
+    k->verbinde( (unsigned short)port, ip->getText() );
+    ip->release();
+    char ret = 0;
+    k->sendeEncrypted( "\2\2", 2 );
+    k->sendeEncrypted( (char*)&klientId, 4 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    bool erf = ret == 1;
+    k->sendeEncrypted( "\3", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+    ms->addGesendet( k->getUploadBytes( 1 ) );
+    k->trenne();
+    k->release();
+    return erf;
+}
+
+bool MSGWeiterleitung::editorServerKlientAbsturz( int klientId )
+{
+    Text *ip = new Text();
+    int port = 0;
+    if( !ms->zDB()->getEditorServer( klientId, ip, &port ) )
+    {
+        ip->release();
+        return 0;
+    }
+    Klient *k = new Klient();
+    unsigned char key[ 20 ] = { 55, 124, 19, 204, 23, 5, 59, 75, 247, 138, 119, 111, 57, 250, 206, 187, 165, 6, 247, 151 };
+    k->setSendeKey( (char*)key, 20 );
+    k->setEmpfangKey( (char*)key, 20 );
+    k->verbinde( (unsigned short)port, ip->getText() );
+    ip->release();
+    char ret = 0;
+    k->sendeEncrypted( "\2\2", 2 );
+    k->sendeEncrypted( (char*)&klientId, 4 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    bool erf = ret == 1;
+    k->sendeEncrypted( "\3", 1 );
+    k->getNachrichtEncrypted( &ret, 1 );
+    ms->addEmpfangen( k->getDownloadBytes( 1 ) );
+    ms->addGesendet( k->getUploadBytes( 1 ) );
+    k->trenne();
+    k->release();
+    return erf;
+}
+
+bool MSGWeiterleitung::spielErstelltAbbrechen( int spielErstelltId )
+{
+	bool ret = 1;
+	Text *ip = new Text( "" );
+	unsigned short port = 0;
+	ret = ret & ms->zDB()->getSpielServerPortIp( spielErstelltId, &port, ip );
+	if( ip->getLength() )
+	{
+		Klient *klient = new Klient();
+		unsigned char key[ 20 ] = { 253, 234, 211, 132, 121, 230, 95, 145, 201, 13, 43, 77, 153, 223, 253, 69, 234, 43, 52, 99 };
+		klient->setSendeKey( (char*)key, 20 );
+		klient->setEmpfangKey( (char*)key, 20 );
+		ret = ret & klient->verbinde( port, ip->getText() );
+		ret = ret & klient->sendeEncrypted( "\x8\x1", 2 );
+		char res = 0;
+		ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+		if( res )
+		{
+			ret = ret & klient->sendeEncrypted( (char*)&spielErstelltId, 4 );
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+		}
+		ret = (char)ret & res;
+		ret = ret & klient->sendeEncrypted( "\x8\x0", 2 );
+		ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+		ret = (char)ret & res;
+		ms->addEmpfangen( klient->getDownloadBytes( 1 ) );
+		ms->addGesendet( klient->getUploadBytes( 1 ) );
+		klient->trenne();
+		klient = klient->release();
+		ip->release();
+	}
+	return ret;
+}
+
+bool MSGWeiterleitung::spielerLeavesGruppe( int gruppeId, int accountId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = ms->zDB()->getSpielerAusGruppe( gruppeId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		if( account == accountId )
+			continue;
+		Text *ip = new Text( "" );
+		unsigned short port = 0;
+		ret = ret & ms->zDB()->getChatServerPortIp( account, &port, ip );
+		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( port, ip->getText() );
+			ret = ret & klient->sendeEncrypted( "\5\x15", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			ret = ret & klient->sendeEncrypted( "\5\x18", 2 );
+			res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			ms->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			ms->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	return ret;
+}
+
+bool MSGWeiterleitung::setGruppeAdmin( int gruppeId, int adminId )
+{
+	if( !adminId || !gruppeId )
+		return 0;
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = ms->zDB()->getSpielerAusGruppe( gruppeId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		Text *ip = new Text( "" );
+		unsigned short port = 0;
+		ret = ret & ms->zDB()->getChatServerPortIp( account, &port, ip );
+		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( port, ip->getText() );
+			ret = ret & klient->sendeEncrypted( "\5\x1B", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&adminId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			ms->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			ms->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	return ret;
+}
+
+bool MSGWeiterleitung::spielerLeavesChatroom( int chatroomId, int accountId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = ms->zDB()->getSpielerAusChatroom( chatroomId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		if( account == accountId )
+			continue;
+		Text *ip = new Text( "" );
+		unsigned short port = 0;
+		ret = ret & ms->zDB()->getChatServerPortIp( account, &port, ip );
+		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( port, ip->getText() );
+			ret = ret & klient->sendeEncrypted( "\5\xE", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&chatroomId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			ms->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			ms->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ip->release();
+	}
+	accId->release();
+	return ret;
+}
+
+bool MSGWeiterleitung::setChatroomAdmin( int chatroomId, int adminId )
+{
+	if( !adminId || !chatroomId )
+		return 0;
+	bool ret = 1;
+	Text *ip = new Text( "" );
+	unsigned short port = 0;
+	ret = ret & ms->zDB()->getChatServerPortIp( adminId, &port, ip );
+	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( port, ip->getText() );
+		ret = ret & klient->sendeEncrypted( "\5\x12", 2 );
+		char res = 0;
+		ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+		if( res )
+		{
+			ret = ret & klient->sendeEncrypted( (char*)&adminId, 4 );
+			ret = ret & klient->sendeEncrypted( (char*)&chatroomId, 4 );
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+		}
+		ret = (char)ret & res;
+		ms->addEmpfangen( klient->getDownloadBytes( 1 ) );
+		ms->addGesendet( klient->getUploadBytes( 1 ) );
+		klient->trenne();
+		klient = klient->release();
+	}
+	ip->release();
+	return ret;
+}
+
+bool MSGWeiterleitung::kickSpielerAusGruppe( int gruppeId )
+{
+	if( !gruppeId )
+		return 0;
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = ms->zDB()->getSpielerAusGruppe( gruppeId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		Text *ip = new Text( "" );
+		unsigned short port = 0;
+		ret = ret & ms->zDB()->getChatServerPortIp( account, &port, ip );
+		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( port, ip->getText() );
+			ret = ret & klient->sendeEncrypted( "\5\x16", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&gruppeId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			ms->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			ms->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		ms->zDB()->kickSpielerAusGruppe( gruppeId, account );
+		ip->release();
+	}
+	accId->release();
+	return ret;
+}
+
+// constant
+
+// Reference Counting
+MSGWeiterleitung *MSGWeiterleitung::getThis()
+{
+	ref++;
+	return this;
+}
+
+MSGWeiterleitung *MSGWeiterleitung::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 123 - 0
MainServer/MainServer.h

@@ -0,0 +1,123 @@
+#ifndef MainServer_H
+#define MainServer_H
+
+#include <Server.h>
+#include <Thread.h>
+#include <InitDatei.h>
+#include "Datenbank.h"
+
+using namespace Framework;
+using namespace Network;
+
+class MainServer : public Thread
+{
+private:
+	Server *server;
+	Server *aServer;
+	InitDatei *dat;
+	MSDatenbank *db;
+	CRITICAL_SECTION cs;
+	int empfangen;
+	int gesendet;
+	int clients;
+	bool end;
+	int ref;
+
+public:
+	// Konstruktor 
+	MainServer( InitDatei *zDat );
+	// Destruktor 
+	virtual ~MainServer();
+	// nicht constant 
+	void runn();
+	void thread();
+	void close();
+	bool serverStarten();
+	void serverBeenden();
+	void addGesendet( int bytes );
+	void addEmpfangen( int bytes );
+	void clientTrennung();
+	// constant 
+	Server *zServer() const;
+	MSDatenbank *zDB() const;
+	bool hatClients() const;
+	// Reference Counting
+	MainServer *getThis();
+	MainServer *release();
+};
+
+class MSAKlient : public Thread
+{
+private:
+	SKlient *klient;
+	Text *name;
+	Text *passwort;
+	int adminId;
+	MainServer *ms;
+
+public:
+	// Konstruktor 
+	MSAKlient( SKlient *klient, MainServer *ms );
+	// Destruktor 
+	virtual ~MSAKlient();
+	// nicht constant 
+	void thread();
+	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum AKlient
+};
+
+class MSKlient : public Thread
+{
+private:
+	SKlient *klient;
+	unsigned int klientNummer;
+	MainServer *ms;
+	bool encrypted;
+
+public:
+	// Konstruktor 
+	MSKlient( SKlient *klient, MainServer *ms );
+	// Destruktor 
+	virtual ~MSKlient();
+	// nicht constant 
+	void thread();
+	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum Klient
+};
+
+class MSGWeiterleitung
+{
+private:
+	MainServer *ms;
+	int ref;
+
+public:
+	// Konstruktor
+	MSGWeiterleitung( MainServer *ms );
+	// Destruktor
+	~MSGWeiterleitung();
+	// nicht constant
+	bool patchServerKlientAbsturz( int klientId );
+	bool registerServerKlientAbsturz( int klientId );
+	bool loginServerKlientAbsturz( int klientId );
+	bool informationServerKlientAbsturz( int klientId );
+	bool chatServerKlientAbsturz( int klientId );
+	bool anmeldungServerKlientAbsturz( int klientId );
+	bool spielServerKlientAbsturz( int klientId );
+	bool shopServerKlientAbsturz( int klientId );
+	bool newsServerKlientAbsturz( int klientId );
+    bool historieServerKlientAbsturz( int klientId );
+    bool kartenServerKlientAbsturz( int klientId );
+    bool editorServerKlientAbsturz( int klientId );
+	bool spielErstelltAbbrechen( int spielErstelltId );
+	bool spielerLeavesGruppe( int gruppeId, int accountId );
+	bool setGruppeAdmin( int gruppeId, int adminId );
+	bool spielerLeavesChatroom( int chatroomId, int accountId );
+	bool setChatroomAdmin( int chatroomId, int adminId );
+	bool kickSpielerAusGruppe( int gruppeId );
+	// constant
+
+	// Reference Counting
+	MSGWeiterleitung *getThis();
+	MSGWeiterleitung *release();
+};
+
+#endif

+ 72 - 0
MainServer/MainServer.vcxproj

@@ -0,0 +1,72 @@
+<?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>{39533d13-f0ab-4243-b957-cdbc8be7ebf4}</ProjectGuid>
+    <Keyword>Linux</Keyword>
+    <RootNamespace>MainServer</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)'=='Debug|x64'">
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/Debug</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;../../../Framework/Debug;..\..\..\..\Allgemein\Network\Network;../../../Network/Debug;..\..\..\..\Allgemein\sql\sql;../../../sql/Debug;$(IncludePath)</IncludePath>
+    <TargetExt />
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetExt />
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/Release</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;../../../Framework/Release;..\..\..\..\Allgemein\Network\Network;../../../Network/Release;..\..\..\..\Allgemein\sql\sql;../../../sql/Release;$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <ItemGroup>
+    <ClCompile Include="Datenbank.cpp" />
+    <ClCompile Include="main.cpp" />
+    <ClCompile Include="MainServer.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Datenbank.h" />
+    <ClInclude Include="MainServer.h" />
+  </ItemGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Link>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/Debug/bin/x64/debug;$(RemoteRootDir)/Network/Debug/bin/x64/debug;$(RemoteRootDir)/Framework/Debug/bin/x64/debug;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <LibraryDependencies>dbgFramework;dbgNetwork;dbgSQL;pq;pthread</LibraryDependencies>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Link>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/Release/bin/x64/release;$(RemoteRootDir)/Network/Release/bin/x64/release;$(RemoteRootDir)/Framework/Release/bin/x64/release;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <LibraryDependencies>Framework;Network;SQL;pq;pthread</LibraryDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>

+ 30 - 0
MainServer/MainServer.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>{f94bb1fe-ad21-4654-b63c-7101de99f34e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{ada07bd7-4c08-4f85-8588-cdf3b1067b54}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="MainServer.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Datenbank.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="MainServer.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="main.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Datenbank.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 57 - 0
MainServer/main.cpp

@@ -0,0 +1,57 @@
+#include "MainServer.h"
+#include <iostream>
+#include <fstream>
+#include <Zeit.h>
+#include <Datei.h>
+#include <Text.h>
+#include <Globals.h>
+
+int main()
+{
+    Framework::initFramework();
+	Zeit *z = getZeit( );
+	Text *pfad = new Text( "../log/main/" );
+	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 << "MS: Startet...\n";
+	std::cout << "MS: Lese init Datei ../data/msInit.ini ...\n";
+
+	InitDatei *dat = new InitDatei( "../data/msInit.ini" );
+	if( !dat->laden() )
+	{
+		std::cout << "MS: 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 << "MS: error: Der Wert '" << w << "' wurde nicht gefunden. Das Programm wird geschlossen.\n";
+            dat->release();
+            exit( 1 );
+        }
+    }
+
+	MainServer *mserver = new MainServer( dat );
+
+	std::cout << "MS: Der Admin Server läuft. Startforgang beendet.\n";
+	mserver->runn();
+
+	mserver->ende();
+	mserver->release();
+	dat->release();
+	std::cout << "MS: Der Server ist heruntergefahren.\n";
+	file.close();
+	std::cout.rdbuf( sbuf );
+    Framework::releaseFramework();
+	return 0;
+}

BIN
MainServer/readme/images/ArchOptions.gif


BIN
MainServer/readme/images/ChangeRemote.gif


BIN
MainServer/readme/images/ManageConnections.gif


BIN
MainServer/readme/images/OutputTypes.gif


BIN
MainServer/readme/images/debuggerexport.png


BIN
MainServer/readme/images/firstconnection.png


BIN
MainServer/readme/images/linker.png


BIN
MainServer/readme/images/postbuild.png


+ 85 - 0
MainServer/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
MainServer/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" "Main Server.sln" /t:rebuild /p:configuration=debug /p:platform=x64
+"D:\Visual Studio 2017\MSBuild\15.0\Bin\MSBuild.exe" "Main Server.sln" /t:rebuild /p:configuration=release /p:platform=x64