Browse Source

Projektdateien hinzufügen.

Kolja Strohm 7 years ago
parent
commit
b63609e380

+ 93 - 0
Chat Server Linux.vcxproj

@@ -0,0 +1,93 @@
+<?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|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x86">
+      <Configuration>Debug</Configuration>
+      <Platform>x86</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x86">
+      <Configuration>Release</Configuration>
+      <Platform>x86</Platform>
+    </ProjectConfiguration>
+    <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>{93f0686b-52b5-4729-8cf2-9692b80cd581}</ProjectGuid>
+    <Keyword>Linux</Keyword>
+    <RootNamespace>Chat_Server_Linux</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|ARM'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Label="Shared" />
+  <ImportGroup Label="PropertySheets" />
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <IncludePath>..\..\..\Allgemein\Framework;..\..\..\Allgemein\Network\Network;..\..\..\Allgemein\sql\sql;$(IncludePath);$(ISenseIncludePath)</IncludePath>
+    <RemoteProjectDir>$(RemoteRootDir)/Server/ChatServer/Release</RemoteProjectDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <IncludePath>..\..\..\Allgemein\Framework;..\..\..\Allgemein\Network\Network;..\..\..\Allgemein\sql\sql;$(IncludePath);$(ISenseIncludePath)</IncludePath>
+    <RemoteProjectDir>$(RemoteRootDir)/Server/ChatServer/Debug</RemoteProjectDir>
+    <TargetName>ChatServer</TargetName>
+  </PropertyGroup>
+  <ItemGroup>
+    <ClCompile Include="Chat Server\ChatServer.cpp" />
+    <ClCompile Include="Chat Server\Datenbank.cpp" />
+    <ClCompile Include="Chat Server\main.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Chat Server\ChatServer.h" />
+    <ClInclude Include="Chat Server\Datenbank.h" />
+  </ItemGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Link>
+      <LibraryDependencies>dbgFramework;dbgNetwork;dbgSQL;%(LibraryDependencies)</LibraryDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Link>
+      <LibraryDependencies>Framework;Network;Sql;%(LibraryDependencies)</LibraryDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>

+ 30 - 0
Chat Server Linux.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>{1d2eb95d-20fa-41dd-9b1c-aa3a8f3f3193}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{2c14fbb2-09c3-41b1-bf0a-11a59ca4ac8b}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Chat Server\ChatServer.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Chat Server\Datenbank.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Chat Server\ChatServer.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Chat Server\Datenbank.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Chat Server\main.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 34 - 0
Chat Server.sln

@@ -0,0 +1,34 @@
+
+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}") = "ChatServer", "ChatServer\ChatServer.vcxproj", "{D2D06294-33CE-4552-A59C-3F691EC2D7F1}"
+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
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Debug|ARM.ActiveCfg = Debug|ARM
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Debug|ARM.Build.0 = Debug|ARM
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Debug|x64.ActiveCfg = Debug|x64
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Debug|x64.Build.0 = Debug|x64
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Debug|x86.ActiveCfg = Debug|x86
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Debug|x86.Build.0 = Debug|x86
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Release|ARM.ActiveCfg = Release|ARM
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Release|ARM.Build.0 = Release|ARM
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Release|x64.ActiveCfg = Release|x64
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Release|x64.Build.0 = Release|x64
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Release|x86.ActiveCfg = Release|x86
+		{D2D06294-33CE-4552-A59C-3F691EC2D7F1}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 3441 - 0
ChatServer/ChatServer.cpp

@@ -0,0 +1,3441 @@
+#include "ChatServer.h"
+#include <iostream>
+#include <Globals.h>
+#ifndef WIN32
+#include <unistd.h>
+#define Sleep( x )   usleep( (x) * 1000 )
+#endif
+
+// Inhalt der ChatServer Klasse aus ChatServer.h
+// Konstruktor 
+ChatServer::ChatServer( InitDatei *zIni )
+	: Thread()
+{
+	Network::Start( 100 );
+	std::cout << "CS: Verbindung mit Datenbank wird hergestellt...\n";
+	db = new CSDatenbank( zIni );
+	klientAnzahl = 0;
+	klients = new RCArray< CSKlient >();
+	empfangen = 0;
+	gesendet = 0;
+	fehler = new Text();
+	ini = zIni->getThis();
+	if( !db->serverAnmelden( zIni ) )
+	{
+		std::cout << "CS: Der Server konnte nicht in die Datenbank eingetragen werden:\n";
+		Text *txt = db->getLetzterFehler();
+		std::cout << txt->getText() << "\nDas Programm wird beendet.";
+		txt->release();
+		exit( 1 );
+	}
+	id = *zIni->zWert( "ServerId" );
+	server = new Server();
+	aServer = new Server();
+	std::cout << "CS: Starten des Admin Servers...\n";
+	if( !aServer->verbinde( (unsigned short)db->getAdminPort( id ), 10 ) )
+	{
+		std::cout << "CS: Der Admin Server konnte nicht gestartet werden. Das Programm wird beendet.\n";
+		exit( 1 );
+	}
+	db->setServerStatus( id, 2 );
+	end = 0;
+	nichtPausiert = 0;
+	InitializeCriticalSection( &cs );
+	ref = 1;
+	if( zIni->zWert( "Aktiv" )->istGleich( "TRUE" ) )
+	{
+		serverStarten();
+		serverFortsetzen();
+	}
+	ref = 1;
+}
+
+// Destruktor 
+ChatServer::~ChatServer()
+{
+	fehler->release();
+	server->trenne();
+	server->release();
+	aServer->trenne();
+	aServer->release();
+	ini->release();
+	db->release();
+	DeleteCriticalSection( &cs );
+	if( klients )
+		klients->release();
+}
+
+// nicht constant 
+void ChatServer::runn()
+{
+	while( !end )
+	{
+		SKlient *klient;
+		klient = aServer->getKlient();
+		if( end && klient )
+		{
+			klient->trenne();
+			klient = klient->release();
+			Sleep( 1000 );
+			return;
+		}
+		if( !klient )
+			return;
+		CSAKlient *clHandle = new CSAKlient( klient, getThis() );
+		clHandle->start();
+	}
+}
+
+void ChatServer::thread()
+{
+	while( 1 )
+	{
+		SKlient *klient;
+		klient = server->getKlient();
+		if( !klient )
+			break;
+		Framework::getThreadRegister()->cleanUpClosedThreads();
+		CSKlient *clHandle = new CSKlient( klient, getThis() );
+		EnterCriticalSection( &cs );
+		klients->set( clHandle, klientAnzahl );
+		klientAnzahl++;
+		LeaveCriticalSection( &cs );
+		clHandle->start();
+	}
+}
+
+void ChatServer::close()
+{
+	db->setServerStatus( id, 1 );
+	server->trenne();
+#ifdef WIN32
+	warteAufThread( 1000 );
+#endif
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+		klients->z( i )->absturz();
+	klients = klients->release();
+	klientAnzahl = 0;
+	LeaveCriticalSection( &cs );
+	ende();
+	run = 0;
+	end = 1;
+	Klient *klient = new Klient();
+	klient->verbinde( aServer->getPort(), "127.0.0.1" );
+	Sleep( 500 );
+	aServer->trenne();
+	klient->release();
+}
+
+bool ChatServer::serverStarten()
+{
+	if( nichtPausiert )
+	{
+		fehler->setText( "Der Server konnte nicht gestartet werden: Der Server läuft bereits." );
+		return 0;
+	}
+	if( server )
+		server->release();
+	server = new Server();
+	if( server->verbinde( (unsigned short)TextZuInt( ini->zWert( "ServerPort" )->getText(), 10 ), 10 ) )
+	{
+		nichtPausiert = 1;
+		start();
+		return 1;
+	}
+	else
+	{
+		serverBeenden();
+		fehler->setText( "Der Server konnte nicht gestartet werden: Eventuell ist der Port in benutzung." );
+		return 0;
+	}
+}
+
+bool ChatServer::serverPause()
+{
+	if( !nichtPausiert )
+	{
+		fehler->setText( "Der Server konnte nicht pausiert werden: Der Server läuft nicht." );
+		return 0;
+	}
+	if( !db->setServerStatus( id, 2 ) )
+	{
+		fehler->setText( "Der Server konnte nicht pausiert werden: " );
+		fehler->append( db->getLetzterFehler() );
+		return 0;
+	}
+	return 1;
+}
+
+bool ChatServer::serverFortsetzen()
+{
+	if( !nichtPausiert )
+	{
+		fehler->setText( "Der Server konnte nicht fortgesetzt werden: Der Server läuft nicht." );
+		return 0;
+	}
+	if( !db->setServerStatus( id, 3 ) )
+	{
+		fehler->setText( "Der Server konnte nicht fortgesetzt werden: " );
+		fehler->append( db->getLetzterFehler() );
+		return 0;
+	}
+	return 1;
+}
+
+bool ChatServer::serverBeenden()
+{
+	if( !nichtPausiert )
+	{
+		fehler->setText( "Der Server konnte nicht beendet werden: Der Server läuft nicht." );
+		return 0;
+	}
+	if( db->serverIstNichtPausiert( id ) )
+	{
+		fehler->setText( "Der Server konnte nicht beendet werden: Der Server muss erst pausiert werden." );
+		return 0;
+	}
+	nichtPausiert = 0;
+	ende();
+	if( server )
+		server->trenne();
+	return 1;
+}
+
+bool ChatServer::setMaxKlients( int mc )
+{
+	if( !db->setMaxClients( id, mc ) )
+	{
+		fehler->setText( "Die maximale Anzahl der Clients konnte nicht gesetzt werden:\n" );
+		fehler->append( db->getLetzterFehler() );
+		return 0;
+	}
+	ini->setWert( "MaxClients", Text() += mc );
+	return 1;
+}
+
+bool ChatServer::absturzKlient( int klientId )
+{
+	bool gefunden = 0;
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+	{
+		if( klients->z( i )->getKlientNummer() == klientId )
+		{
+			klients->z( i )->absturz();
+			klients->remove( i );
+			klientAnzahl--;
+			gefunden = 1;
+			i--;
+		}
+	}
+	LeaveCriticalSection( &cs );
+	return gefunden;
+}
+
+bool ChatServer::removeAccount( int accId )
+{
+	bool gefunden = 0;
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+	{
+		if( klients->z( i )->getAccountId() == accId )
+		{
+			klients->remove( i );
+			klientAnzahl--;
+			gefunden = 1;
+			i--;
+		}
+	}
+	LeaveCriticalSection( &cs );
+	return gefunden;
+}
+
+bool ChatServer::removeKlient( int klientId )
+{
+	bool gefunden = 0;
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+	{
+		if( klients->z( i )->getKlientNummer() == klientId )
+		{
+			klients->z( i )->trenne();
+			klients->remove( i );
+			klientAnzahl--;
+			gefunden = 1;
+			i--;
+		}
+	}
+	LeaveCriticalSection( &cs );
+	return gefunden;
+}
+
+bool ChatServer::removeKlient( CSKlient *zKlient )
+{
+	bool gefunden = 0;
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+	{
+		if( klients->z( i ) == zKlient )
+		{
+			klients->z( i )->trenne();
+			klients->remove( i );
+			klientAnzahl--;
+			gefunden = 1;
+			break;
+		}
+	}
+	LeaveCriticalSection( &cs );
+	return gefunden;
+}
+
+void ChatServer::addGesendet( int bytes )
+{
+	gesendet += bytes;
+}
+
+void ChatServer::addEmpfangen( int bytes )
+{
+	empfangen += bytes;
+}
+
+int ChatServer::getKlientStatus( int klientNummer, CSKlient *zKlient )
+{
+	bool empf = 0;
+	bool send = 0;
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+	{
+		if( klients->z( i )->getKlientNummer() == klientNummer &&  klients->z( i ) != zKlient )
+		{
+			if( klients->z( i )->istEmpfang() )
+				empf = 1;
+			else
+				send = 1;
+		}
+	}
+	LeaveCriticalSection( &cs );
+	if( !empf )
+		return 0;
+	if( !send )
+		return 1;
+	return 2;
+}
+
+CSKlient *ChatServer::zSendeKlient( int accountId )
+{
+	CSKlient *ret = 0;
+	EnterCriticalSection( &cs );
+	for( int i = 0; i < klientAnzahl; i++ )
+	{
+		if( klients->z( i )->getAccountId() == accountId && !klients->z( i )->istEmpfang() )
+		{
+			ret = klients->z( i );
+			break;
+		}
+	}
+	LeaveCriticalSection( &cs );
+	return ret;
+}
+
+// constant 
+bool ChatServer::istAn() const
+{
+	return db->serverIstNichtPausiert( id );
+}
+
+Server *ChatServer::zServer() const
+{
+	return server;
+}
+
+CSDatenbank *ChatServer::zDB() const
+{
+	return db;
+}
+
+bool ChatServer::hatClients() const
+{
+	return klientAnzahl > 0;
+}
+
+int ChatServer::getId() const
+{
+	return id;
+}
+
+char *ChatServer::getLetzterFehler() const
+{
+	return fehler->getText();
+}
+
+// Reference Counting
+ChatServer *ChatServer::getThis()
+{
+	ref++;
+	return this;
+}
+
+ChatServer *ChatServer::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der CSAKlient Klasse aus ChatServer.h
+// Konstruktor 
+CSAKlient::CSAKlient( SKlient *klient, ChatServer *cs )
+	: Thread()
+{
+	this->klient = klient;
+	unsigned char key[ 20 ] = { 51, 206, 196, 230, 31, 97, 186, 90, 5, 0, 166, 28, 40, 141, 16, 55, 36, 181, 203, 236 };
+	klient->setSendeKey( (char*)key, 20 );
+	klient->setEmpfangKey( (char*)key, 20 );
+	name = new Text( "" );
+	passwort = new Text( "" );
+	adminId = 0;
+	this->cs = cs;
+}
+
+// Destruktor 
+CSAKlient::~CSAKlient()
+{
+	klient->trenne();
+	klient->release();
+	cs->release();
+	name->release();
+	passwort->release();
+}
+
+// nicht constant 
+void CSAKlient::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 = cs->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( cs->zDB()->adminHatRecht( adminId, Admin_Recht::CSStarten ) )
+					{
+						if( !cs->serverStarten() )
+						{
+							Text *err = new Text();
+							err->append( cs->getLetzterFehler() );
+							errorZuKlient( err->getText() );
+							err->release();
+						}
+						else
+							klient->sendeEncrypted( "\1", 1 );
+					}
+					else
+						errorZuKlient( "Du bist nicht berechtigt den Server zu starten." );
+				}
+				break;
+			case 5: // Server beenden
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					if( cs->zDB()->adminHatRecht( adminId, Admin_Recht::CSBeenden ) )
+					{
+						if( cs->serverBeenden() )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							Text *err = new Text();
+							err->append( cs->getLetzterFehler() );
+							errorZuKlient( err->getText() );
+							err->release();
+						}
+					}
+					else
+						errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+				}
+				break;
+			case 6: // Programm Schließen
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					bool ok = 0;
+					if( cs->isRunning() )
+					{
+						if( cs->zDB()->adminHatRecht( adminId, Admin_Recht::CSBeenden ) )
+						{
+							if( cs->serverBeenden() )
+								ok = 1;
+							else
+							{
+								Text *err = new Text();
+								err->append( cs->getLetzterFehler() );
+								errorZuKlient( err->getText() );
+								err->release();
+							}
+						}
+						else
+							errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+					}
+					else
+						ok = 1;
+					if( ok && cs->hatClients() )
+					{
+						errorZuKlient( "Es sind noch Klients Online. Bitte versuche es später erneut." );
+						break;
+					}
+					if( ok )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						std::cout << "CS: Der Server wird von Benutzer " << adminId << " heruntergefahren.\n";
+						cs->close();
+						br = 1;
+					}
+				}
+				break;
+			case 7: // Progtamm abstürzen
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					bool ok = 0;
+					if( cs->isRunning() )
+					{
+						if( cs->zDB()->adminHatRecht( adminId, Admin_Recht::CSBeenden ) )
+						{
+							cs->serverBeenden();
+							ok = 1;
+						}
+						else
+							errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+					}
+					else
+						ok = 1;
+					if( ok )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						std::cout << "CS: Der Server wurde von Benutzer " << adminId << " terminiert.\n";
+						cs->close();
+						br = 1;
+					}
+				}
+				break;
+			case 8: // Status Frage
+				if( 1 )
+				{
+					char status = 0;
+					if( cs->isRunning() )
+					{
+						status = 1;
+						if( cs->istAn() )
+							status = 2;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					klient->sendeEncrypted( &status, 1 );
+				}
+				break;
+			case 9: // Server pausieren
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					klient->sendeEncrypted( "\1", 1 );
+					char pause = 0;
+					klient->getNachrichtEncrypted( &pause, 1 );
+					if( cs->zDB()->adminHatRecht( adminId, Admin_Recht::CSPausieren ) )
+					{
+						bool ok = 0;
+						if( pause )
+							ok = cs->serverPause();
+						else
+							ok = cs->serverFortsetzen();
+						if( ok )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							Text *err = new Text();
+							err->append( cs->getLetzterFehler() );
+							errorZuKlient( err->getText() );
+							err->release();
+						}
+					}
+					else
+					{
+						if( pause )
+							errorZuKlient( "Du bist nicht berechtigt den Server zu pausieren." );
+						else
+							errorZuKlient( "Du bist nicht berechtigt den Server fortzusetzen." );
+					}
+				}
+				break;
+			case 0xA: // maximale Anzahl der Clients setzen
+				if( !adminId )
+					errorZuKlient( "Du musst dich einloggen." );
+				else
+				{
+					klient->sendeEncrypted( "\1", 1 );
+					int maxC = 0;
+					klient->getNachrichtEncrypted( (char*)&maxC, 4 );
+					if( cs->zDB()->adminHatRecht( adminId, Admin_Recht::CSMCChange ) )
+					{
+						if( cs->setMaxKlients( maxC ) )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							Text *err = new Text();
+							err->append( cs->getLetzterFehler() );
+							errorZuKlient( err->getText() );
+							err->release();
+						}
+					}
+					else
+						errorZuKlient( "Du bist nicht berechtigt die maximale Anzahl der Clients zu verändern." );
+				}
+				break;
+			case 0xC: // klient absturtz
+				if( 1 )
+				{
+					klient->sendeEncrypted( "\1", 1 );
+					int klientId = 0;
+					klient->getNachrichtEncrypted( (char*)&klientId, 4 );
+					if( klientId && cs->absturzKlient( klientId ) )
+						klient->sendeEncrypted( "\1", 1 );
+					else
+						klient->sendeEncrypted( "\0", 1 );
+				}
+				break;
+			default:
+				errorZuKlient( "Unbekannte Nachricht!" );
+				break;
+			}
+			if( br )
+				break;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+		}
+	}
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	delete this;
+}
+
+void CSAKlient::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 CSKlient aus ChatServer.h
+// Konstruktor 
+CSKlient::CSKlient( SKlient *klient, ChatServer *cs )
+	: Thread()
+{
+	this->klient = 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 );
+	klientNummer = 0;
+	this->cs = cs;
+	accountId = 0;
+	empfangen = 1;
+	InitializeCriticalSection( &ts );
+	ref = 1;
+}
+
+// Destruktor 
+CSKlient::~CSKlient()
+{
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	klient->release();
+	cs->release();
+	DeleteCriticalSection( &ts );
+}
+
+// nicht constant 
+void CSKlient::lock()
+{
+	EnterCriticalSection( &ts );
+}
+
+void CSKlient::unlock()
+{
+	LeaveCriticalSection( &ts );
+}
+
+void CSKlient::absturz()
+{
+#ifdef WIN32
+	if( GetCurrentThreadId() != GetThreadId( getThreadHandle() ) )
+		ende();
+#else
+	ende();
+#endif
+	klient->trenne();
+	if( empfangen )
+	{
+		cs->zDB()->unregisterKlient( klientNummer, cs->getId() );
+		MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+		weiter->accountOffline( accountId );
+		delete weiter;
+	}
+}
+
+void CSKlient::thread()
+{
+	int unbekannt = 0;
+	while( 1 )
+	{
+		char c = 0;
+		if( !klient->getNachrichtEncrypted( &c, 1 ) )
+			break;
+		else
+		{
+			bool br = 0;
+			switch( c )
+			{
+			case 1: // Klient identifikation
+				klient->getNachrichtEncrypted( (char*)&klientNummer, 4 );
+				if( !cs->zDB()->proveKlient( klientNummer, cs->getId() ) )
+				{
+					klientNummer = 0;
+					errorZuKlient( "Du bist nicht für diesen Server eingetragen" );
+				}
+				if( klientNummer )
+				{
+					accountId = cs->zDB()->getKlientAccountId( klientNummer );
+					if( !accountId )
+					{
+						errorZuKlient( "Du bist nicht online" );
+						klientNummer = 0;
+					}
+					else
+					{
+						int status = cs->getKlientStatus( klientNummer, this );
+						if( status == 2 )
+						{
+							klientNummer = 0;
+							accountId = 0;
+							errorZuKlient( "Diese Klient Nummer ist bereits verbunden" );
+						}
+						else
+						{
+							Text *key = cs->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();
+								if( status == 1 )
+								{
+									empfangen = 0;
+									MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+									weiter->accountOnline( accountId );
+									delete weiter;
+									br = 1;
+								}
+							}
+						}
+					}
+				}
+				break;
+			case 2: // Main / Erhaltung Server message
+				if( 1 )
+				{
+					char befehl = 0;
+					klient->getNachrichtEncrypted( &befehl, 1 );
+					switch( befehl )
+					{
+					case 2: // klient absturtz
+						if( 1 )
+						{
+							int klientId = 0;
+							klient->getNachrichtEncrypted( (char*)&klientId, 4 );
+							if( klientId && cs->absturzKlient( klientId ) )
+								klient->sendeEncrypted( "\1", 1 );
+							else
+								klient->sendeEncrypted( "\0", 1 );
+						}
+						break;
+					default:
+						errorZuKlient( "Befehl nicht bekannt!" );
+						break;
+					}
+				}
+				break;
+			case 3: // Verbindungsende
+				if( 1 )
+				{
+					lock();
+					klient->sendeEncrypted( "\1", 1 );
+					unlock();
+					br = 1;
+				}
+				break;
+			case 4: // unregister Klient
+				if( !klientNummer )
+				{
+					klient->sendeEncrypted( "\0", 1 );
+					CSKlient *c = cs->zSendeKlient( accountId );
+					if( c )
+						c->errorZuKlient( "Du bist nicht Identifiziert." );
+					break;
+				}
+				cs->zDB()->unregisterKlient( klientNummer, cs->getId() );
+				klient->sendeEncrypted( "\1", 1 );
+				break;
+			case 5: // Server message
+				if( 1 )
+				{
+					char byte = 0;
+					char res = 1;
+					klient->getNachrichtEncrypted( &byte, 1 );
+					switch( byte )
+					{
+					case 1: // kick Klient
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int id = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&id, 4 ) );
+							CSKlient *c = cs->zSendeKlient( id );
+							if( c )
+							{
+								c->kick();
+								cs->absturzKlient( c->getKlientNummer() );
+							}
+							cs->removeAccount( id );
+						}
+						break;
+					case 2: // Account kommt online
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int freundId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&freundId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( freundId );
+							if( klient )
+								res = (char)( res & (char)klient->freundOnline( accId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 3: // Account geht offline
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int freundId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&freundId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( freundId );
+							if( klient )
+								res = (char)( res & (char)klient->freundOffline( accId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 4: // Chat nachricht
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int vonAcc = 0;
+							int zuAcc = 0;
+							char len = 0;
+							char *nachricht = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&vonAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( &len, 1 ) );
+							if( len )
+							{
+								nachricht = new char[ len + 1 ];
+								nachricht[ (int)len ] = 0;
+								res = (char)( res & (char)klient->getNachrichtEncrypted( nachricht, len ) );
+								CSKlient *klient = cs->zSendeKlient( zuAcc );
+								if( klient )
+									res = (char)( res & (char)klient->nachricht( vonAcc, nachricht ) );
+								else
+									res = 0;
+							}
+							delete[]nachricht;
+						}
+						break;
+					case 5: // Gruppe einladung
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int vonAcc = 0;
+							int zuAcc = 0;
+							int gruppeId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&vonAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->gruppeEinladung( vonAcc, gruppeId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 6: // Account Status ändert sich
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int freundId = 0;
+							char len = 0;
+							char *status = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&freundId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( &len, 1 ) );
+							if( len )
+							{
+								status = new char[ len + 1 ];
+								status[ (int)len ] = 0;
+								res = (char)( res & (char)klient->getNachrichtEncrypted( status, len ) );
+								CSKlient *klient = cs->zSendeKlient( freundId );
+								if( klient )
+									res = (char)( res & (char)klient->accountStatusChange( accId, status ) );
+								else
+									res = 0;
+							}
+							delete[]status;
+						}
+						break;
+					case 7: // Account Name ändert sich
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int freundId = 0;
+							char len = 0;
+							char *name = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&freundId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( &len, 1 ) );
+							if( len )
+							{
+								name = new char[ len + 1 ];
+								name[ (int)len ] = 0;
+								res = (char)( res & (char)klient->getNachrichtEncrypted( name, len ) );
+								CSKlient *klient = cs->zSendeKlient( freundId );
+								if( klient )
+									res = (char)( res & (char)klient->accountNameChange( accId, name ) );
+								else
+									res = 0;
+							}
+							delete[]name;
+						}
+						break;
+					case 8: // Kein Freund mehr
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int freundId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&freundId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( freundId );
+							if( klient )
+								res = (char)( res & (char)klient->keinFreundMehr( accId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 9: // Freundesanfrage
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int freundId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&freundId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( freundId );
+							if( klient )
+								res = (char)( res & (char)klient->freundesAnfrage( accId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0xA: // Neuer Freund
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int freundId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&freundId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( freundId );
+							if( klient )
+								res = (char)( res & (char)klient->neuerFreund( accountId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0xB: // Einladung zum Chatroom
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int vonAcc = 0;
+							int zuAcc = 0;
+							int chatroomId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&vonAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&chatroomId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->einladungZumChatroom( vonAcc, chatroomId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0xC: // Spieler betritt Chatroom
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int zuAcc = 0;
+							int chatroomId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&chatroomId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->spielerBetrittChatroom( chatroomId, accId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0xD: // Chatroom nachricht
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int vonAcc = 0;
+							int zuAcc = 0;
+							int chatroomId = 0;
+							char len = 0;
+							char *nachricht = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&vonAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&chatroomId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( &len, 1 ) );
+							if( len )
+							{
+								nachricht = new char[ len + 1 ];
+								nachricht[ (int)len ] = 0;
+								res = (char)( res & (char)klient->getNachrichtEncrypted( nachricht, len ) );
+								CSKlient *klient = cs->zSendeKlient( zuAcc );
+								if( klient )
+									res = (char)( res & (char)klient->chatroomNachricht( chatroomId, vonAcc, nachricht ) );
+								else
+									res = 0;
+							}
+							delete[]nachricht;
+						}
+						break;
+					case 0xE: // Spieler verlässt Chatroom
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int zuAcc = 0;
+							int chatroomId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&chatroomId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->spielerLeavesChatroom( chatroomId, accId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0xF: // Freund Einladung abgelehnt
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int freundId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&freundId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( freundId );
+							if( klient )
+								res = (char)( res & (char)klient->freundesAnfrageAbgelehnt( accId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x10: // Chatroom Einladungabgelehnt
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int accId = 0;
+							int zuAcc = 0;
+							int chatroomId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&chatroomId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->einladungZumChatroomAbgelehnt( accId, chatroomId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x11: // Fehler
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							char len = 0;
+							char *nachricht = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( &len, 1 ) );
+							if( len )
+							{
+								nachricht = new char[ len + 1 ];
+								nachricht[ (int)len ] = 0;
+								res = (char)( res & (char)klient->getNachrichtEncrypted( nachricht, len ) );
+								CSKlient *klient = cs->zSendeKlient( zuAcc );
+								if( klient )
+									res = (char)( res & (char)klient->errorZuKlient( nachricht ) );
+								else
+									res = 0;
+							}
+							delete[]nachricht;
+						}
+						break;
+					case 0x12: // Chatroom Admin
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int chatroomId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&chatroomId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->chatroomAdmin( chatroomId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x13: // Chatroom Kick
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int chatroomId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&chatroomId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->chatroomKick( chatroomId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x14: // spieler betritt gruppe
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int accountId = 0;
+							int gruppeId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accountId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->spielerBertittGruppe( accountId, gruppeId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x15: // spieler verlässt gruppe
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int accountId = 0;
+							int gruppeId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accountId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->spielerLeavesGruppe( accountId, gruppeId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x16: // kick spieler aus gruppe
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int gruppeId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->kickAusGruppe( gruppeId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x17: // gruppe angemeldet
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int gruppeId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->gruppeAnmelden( gruppeId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x18: // gruppe abgemeldet
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int gruppeId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->gruppeAbmelden( gruppeId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x19: // gruppe nachricht
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int gruppeId = 0;
+							char len;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( &len, 1 ) );
+							char *nachricht = new char[ len + 1 ];
+							nachricht[ (int)len ] = 0;
+							if( len )
+								res = (char)( res & (char)klient->getNachrichtEncrypted( nachricht, len ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->gruppeNachricht( gruppeId, nachricht ) );
+							else
+								res = 0;
+							delete[]nachricht;
+						}
+						break;
+					case 0x1A: // gruppe spiel starten
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int gruppeId = 0;
+							char starten;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( &starten, 1 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->gruppeSpielStarten( gruppeId, starten == 1 ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x1B: // gruppe admin
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int adminId = 0;
+							int gruppeId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&adminId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->setGruppeAdmin( gruppeId, adminId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x1C: // gruppe Einladung abgelehnt
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int accountId = 0;
+							int gruppeId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accountId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->gruppeEinladungAbgelehnt( gruppeId, accountId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x1D: // Spiel Server verbindungs aufforderung
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							unsigned short port;
+							unsigned char *ip = new unsigned char[ 4 ];
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&port, 2 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)ip, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->spielServerVerbindungsAnfrage( port, ip ) );
+							else
+								res = 0;
+							delete[] ip;
+						}
+						break;
+					case 0x1E: // gruppe einladung Abbrechen
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int gruppeId = 0;
+							int accountId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accountId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->gruppeEinladungAbgebrochen( gruppeId, accountId ) );
+							else
+								res = 0;
+						}
+						break;
+					case 0x1F: // gruppe einladung Neu
+						if( 1 )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							int zuAcc = 0;
+							int gruppeId = 0;
+							int accountId = 0;
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&zuAcc, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&gruppeId, 4 ) );
+							res = (char)( res & (char)klient->getNachrichtEncrypted( (char*)&accountId, 4 ) );
+							CSKlient *klient = cs->zSendeKlient( zuAcc );
+							if( klient )
+								res = (char)( res & (char)klient->gruppeEinladungNeu( gruppeId, accountId ) );
+							else
+								res = 0;
+						}
+						break;
+					default:
+						res = 0;
+						break;
+					}
+					klient->sendeEncrypted( &res, 1 );
+				}
+				break;
+			case 6: // Chat Nachricht
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int zuAccount = 0;
+					char len = 0;
+					char *nachricht = 0;
+					klient->getNachrichtEncrypted( (char*)&zuAccount, 4 );
+					klient->getNachrichtEncrypted( &len, 1 );
+					if( len )
+					{
+						nachricht = new char[ len + 1 ];
+						nachricht[ (int)len ] = 0;
+						klient->getNachrichtEncrypted( nachricht, len );
+						MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+						if( !weiter->chatNachricht( accountId, zuAccount, nachricht ) )
+						{
+							cs->zDB()->speicherChatNachricht( accountId, zuAccount, nachricht );
+							CSKlient *c = cs->zSendeKlient( accountId );
+							if( c )
+								c->errorZuKlient( "Der Account ist momentan nicht erreichbar." );
+						}
+						delete weiter;
+						delete[]nachricht;
+					}
+				}
+				break;
+			case 8: // Account Name ändern
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					char len;
+					char *name;
+					klient->getNachrichtEncrypted( &len, 1 );
+					if( len )
+					{
+						name = new char[ len + 1 ];
+						name[ (int)len ] = 0;
+						klient->getNachrichtEncrypted( name, len );
+						if( cs->zDB()->accountNameChange( accountId, name ) )
+						{
+							klient->sendeEncrypted( "\1", 1 );
+							MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+							weiter->accountNameChange( accountId, name );
+							delete weiter;
+						}
+						else
+						{
+							klient->sendeEncrypted( "\0", 1 );
+							CSKlient *c = cs->zSendeKlient( accountId );
+							if( c )
+								c->errorZuKlient( "Beim ändern des Namens ist ein Fehler aufgetreten." );
+						}
+						delete[]name;
+					}
+				}
+				break;
+			case 9: // Freundschaft beenden
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int freundId = 0;
+					klient->getNachrichtEncrypted( (char*)&freundId, 4 );
+					if( cs->zDB()->beendeFreundschaft( accountId, freundId ) )
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+						weiter->accountKeinFreundMehr( accountId, freundId );
+						weiter->accountKeinFreundMehr( freundId, accountId );
+						delete weiter;
+					}
+					else
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Die Freundschaft konnte nicht beendet werden." );
+					}
+				}
+				break;
+			case 0xA: // Freundschaftsanfrage senden
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int freundId = 0;
+					klient->getNachrichtEncrypted( (char*)&freundId, 4 );
+					if( cs->zDB()->proveFreundschaftsAnfrage( accountId, freundId ) )
+					{
+						MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+						if( !weiter->freundesAnfrage( accountId, freundId ) )
+							cs->zDB()->saveFreundschaftsAnfrage( accountId, freundId );
+						klient->sendeEncrypted( "\1", 1 );
+						delete weiter;
+					}
+					else
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Diesem Account konnte keine Freundschaftsanfrage gesendet werden." );
+					}
+				}
+				break;
+			case 0xB: // Freundschaftsanfrage beantworten
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int zuAccount = 0;
+					char ok = 0;
+					klient->getNachrichtEncrypted( (char*)&zuAccount, 4 );
+					klient->getNachrichtEncrypted( &ok, 1 );
+					MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+					if( !ok )
+					{
+						weiter->freundEinladungAbgelehnt( accountId, zuAccount );
+						klient->sendeEncrypted( "\1", 1 );
+					}
+					else
+					{
+						if( cs->zDB()->neueFreundschaft( accountId, zuAccount ) )
+						{
+							weiter->neuerFreund( accountId, zuAccount );
+							weiter->neuerFreund( zuAccount, accountId );
+							if( cs->zDB()->accountIstOnline( zuAccount ) )
+							{
+								weiter->accountOnline( zuAccount );
+								weiter->accountOnline( accountId );
+							}
+							klient->sendeEncrypted( "\1", 1 );
+						}
+						else
+						{
+							klient->sendeEncrypted( "\0", 1 );
+							CSKlient *c = cs->zSendeKlient( accountId );
+							if( c )
+								c->errorZuKlient( "Fehler beim erstellen der neuen Freundschaft." );
+							weiter->fehler( zuAccount, "Fehler beim erstellen der neuen Freundschaft." );
+						}
+					}
+					delete weiter;
+				}
+				break;
+			case 0xC: // Chatroom erstellen
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					char nLen = 0;
+					char *name = 0;
+					klient->getNachrichtEncrypted( &nLen, 1 );
+					if( nLen )
+					{
+						name = new char[ nLen + 1 ];
+						name[ (int)nLen ] = 0;
+						klient->getNachrichtEncrypted( name, nLen );
+					}
+					if( !name )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du musst einen Namen eingeben." );
+					}
+					else
+					{
+						klient->sendeEncrypted( "\1", 1 );
+						int id = cs->zDB()->chatroomErstellen( accountId, name );
+						klient->sendeEncrypted( (char*)&id, 4 );
+						if( !id )
+						{
+							CSKlient *c = cs->zSendeKlient( accountId );
+							if( c )
+								c->errorZuKlient( "Das Chatroom konnte nicht erstellt werden." );
+						}
+						else
+						{
+							CSKlient *c = cs->zSendeKlient( accountId );
+							if( c )
+							{
+								c->spielerBetrittChatroom( id, accountId );
+								c->chatroomAdmin( id );
+							}
+						}
+					}
+					delete[]name;
+				}
+				break;
+			case 0xD: // Zum Chatroom einladen
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int zuAccountId = 0;
+					int chatroomId = 0;
+					klient->getNachrichtEncrypted( (char*)&zuAccountId, 4 );
+					klient->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+					if( cs->zDB()->proveChatroomEinladung( accountId, zuAccountId, chatroomId ) )
+					{
+						MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+						if( weiter->einladungZumChatroom( accountId, zuAccountId, chatroomId ) )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							klient->sendeEncrypted( "\0", 1 );
+							if( weiter->getLetzterFehler() )
+							{
+								CSKlient *c = cs->zSendeKlient( accountId );
+								if( c )
+									c->errorZuKlient( weiter->getLetzterFehler() );
+							}
+						}
+						delete weiter;
+					}
+					else
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Der Account konnte nicht eingeladen werden." );
+					}
+				}
+				break;
+			case 0xE: // Chatroom einladung ablehnen
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int zuAccountId = 0;
+					int chatroomId = 0;
+					klient->getNachrichtEncrypted( (char*)&zuAccountId, 4 );
+					klient->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+					MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+					weiter->chatroomEinladungAbgelehnt( accountId, chatroomId, zuAccountId );
+					delete weiter;
+					klient->sendeEncrypted( "\1", 1 );
+				}
+				break;
+			case 0xF: // Chatroom betreten
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int chatroomId = 0;
+					klient->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+					if( cs->zDB()->chatroomBeitreten( accountId, chatroomId ) )
+					{
+						MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+						weiter->spielerBetrittChatroom( accountId, chatroomId );
+						delete weiter;
+						klient->sendeEncrypted( "\1", 1 );
+						Array< int > *accounts = new Array< int >();
+						int anzahl = cs->zDB()->getChatroomAccount( chatroomId, accounts );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+						{
+							if( !c->spielerImChatroom( chatroomId, (char)anzahl, accounts ) )
+								c->errorZuKlient( "Fehler beim senden der momentanen Spieler im Chatroom." );
+						}
+						accounts->release();
+					}
+					else
+						klient->sendeEncrypted( "\0", 1 );
+				}
+				break;
+			case 0x10: // Chatroom Nachricht
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int chatroomId = 0;
+					char len = 0;
+					char *nachricht = 0;
+					klient->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+					klient->getNachrichtEncrypted( &len, 1 );
+					if( len )
+					{
+						nachricht = new char[ len + 1 ];
+						nachricht[ (int)len ] = 0;
+						klient->getNachrichtEncrypted( nachricht, len );
+						Text *message = cs->zDB()->getAccountRufName( accountId );
+						message->append( ": " );
+						message->append( nachricht );
+						MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+						if( weiter->chatroomNachricht( accountId, message->getText(), chatroomId ) )
+							klient->sendeEncrypted( "\1", 1 );
+						else
+						{
+							klient->sendeEncrypted( "\0", 1 );
+							if( weiter->getLetzterFehler() )
+							{
+								CSKlient *c = cs->zSendeKlient( accountId );
+								if( c )
+									c->errorZuKlient( weiter->getLetzterFehler() );
+							}
+						}
+						message->release();
+						delete weiter;
+						delete[]nachricht;
+					}
+					else
+						klient->sendeEncrypted( "\0", 1 );
+				}
+				break;
+			case 0x11: // Chatroom verlassen
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int chatroomId = 0;
+					klient->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+					int aktion = cs->zDB()->chatroomVerlassen( accountId, chatroomId );
+					if( !aktion )
+						klient->sendeEncrypted( "\0", 1 );
+					else
+					{
+						if( aktion == 3 )
+						{
+							MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+							weiter->chatroomAdmin( chatroomId, cs->zDB()->getChatroomAdmin( chatroomId ) );
+							delete weiter;
+						}
+						if( aktion != 2 )
+						{
+							MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+							weiter->spielerLeavestChatroom( accountId, chatroomId );
+							delete weiter;
+						}
+						klient->sendeEncrypted( "\1", 1 );
+					}
+				}
+				break;
+			case 0x12: // Chatroom Kick
+				if( 1 )
+				{
+					if( !accountId || !klientNummer )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					int chatroomId = 0;
+					int accountId = 0;
+					klient->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+					klient->getNachrichtEncrypted( (char*)&accountId, 4 );
+					if( accountId == (int)this->accountId )
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du kannst dich selbst nicht kicken." );
+						break;
+					}
+					if( cs->zDB()->getChatroomAdmin( chatroomId ) == (int)this->accountId )
+					{
+						if( cs->zDB()->chatroomVerlassen( accountId, chatroomId ) )
+						{
+							MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+							weiter->chatroomKick( chatroomId, accountId );
+							weiter->spielerLeavestChatroom( accountId, chatroomId );
+							delete weiter;
+							klient->sendeEncrypted( "\1", 1 );
+						}
+						else
+						{
+							klient->sendeEncrypted( "\0", 1 );
+							CSKlient *c = cs->zSendeKlient( accountId );
+							if( c )
+								c->errorZuKlient( "Der Spieler konnte nicht entfernt werden." );
+						}
+					}
+					else
+					{
+						klient->sendeEncrypted( "\0", 1 );
+						CSKlient *c = cs->zSendeKlient( accountId );
+						if( c )
+							c->errorZuKlient( "Du bist nicht der Administrator dieses Chatrooms." );
+					}
+				}
+				break;
+			case 0x13: // Anfrage nach Freundes Liste
+				if( 1 )
+				{
+					klient->sendeEncrypted( "\1", 1 );
+					Array< int > *freundId = new Array< int >();
+					int anz = cs->zDB()->getAccountFreunde( accountId, freundId );
+					CSKlient *c = cs->zSendeKlient( accountId );
+					if( c )
+						c->freunde( (char)anz, freundId );
+					freundId->release();
+					freundId = new Array< int >();
+					anz = cs->zDB()->getAccountOnlineFreunde( accountId, freundId );
+					for( int i = 0; i < anz; i++ )
+					{
+						if( c )
+							c->freundOnline( freundId->get( i ) );
+					}
+					freundId->release();
+				}
+				break;
+			case 0x14: // Anfrage nach chat nachrichten in abwesenheit
+				if( 1 )
+				{
+					klient->sendeEncrypted( "\1", 1 );
+					Array< int > *vonAccount = new Array< int >();
+					RCArray< Text > *nachricht = new RCArray< Text >();
+					int anzahl = cs->zDB()->getChatNachrichten( accountId, vonAccount, nachricht );
+					CSKlient *c = cs->zSendeKlient( accountId );
+					if( c )
+					{
+						for( int i = 0; i < anzahl; i++ )
+							c->nachricht( vonAccount->get( i ), nachricht->z( i )->getText() );
+					}
+					vonAccount->leeren();
+					nachricht->release();
+					anzahl = cs->zDB()->getFreundschaftsAnfragen( accountId, vonAccount );
+					if( c )
+					{
+						for( int i = 0; i < anzahl; i++ )
+							c->freundesAnfrage( vonAccount->get( i ) );
+					}
+					vonAccount->release();
+				}
+				break;
+			case 0x15: // ping
+				if( 1 )
+				{
+					if( !klientNummer )
+					{
+						errorZuKlient( "Du bist nicht Identifiziert." );
+						break;
+					}
+					klient->sendeEncrypted( "\1", 1 );
+					CSKlient *c = cs->zSendeKlient( accountId );
+					if( c )
+						c->keepAlive();
+				}
+				break;
+			default:
+				unbekannt++;
+				errorZuKlient( "Unbekannte Nachricht!" );
+				break;
+			}
+			if( br || unbekannt >= 10 )
+				break;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+		}
+	}
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	if( empfangen )
+	{
+		trenne();
+		if( klientNummer )
+		{
+			if( accountId )
+			{
+				MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+				weiter->accountOffline( accountId );
+				delete weiter;
+			}
+			cs->removeKlient( klientNummer );
+		}
+		else
+			cs->removeKlient( this );
+	}
+}
+
+bool CSKlient::kick()
+{
+	lock();
+	if( empfangen )
+	{
+		klient->trenne();
+		warteAufThread( 100 );
+		ende();
+		MSGWeiterleitung *weiter = new MSGWeiterleitung( cs->getThis() );
+		weiter->accountOffline( accountId );
+		delete weiter;
+	}
+	else
+	{
+		klient->sendeEncrypted( "\1", 1 );
+		Sleep( 100 );
+		klient->trenne();
+	}
+	unlock();
+	return 1;
+}
+
+bool CSKlient::nachricht( int vonAccount, const char *txt )
+{
+	if( empfangen )
+		return 0;
+	char len = (char)textLength( txt );
+	if( len )
+	{
+		lock();
+		klient->sendeEncrypted( "\4", 1 );
+		klient->sendeEncrypted( (char*)&vonAccount, 4 );
+		klient->sendeEncrypted( &len, 1 );
+		klient->sendeEncrypted( txt, len );
+		unlock();
+	}
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::gruppeEinladung( int vonAccount, int gruppeId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\5", 1 );
+	klient->sendeEncrypted( (char*)&vonAccount, 4 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::accountStatusChange( int account, const char *status )
+{
+	if( empfangen )
+		return 0;
+	char len = (char)( status ? textLength( status ) : 0 );
+	if( len )
+	{
+		lock();
+		klient->sendeEncrypted( "\6", 1 );
+		klient->sendeEncrypted( (char*)&account, 4 );
+		klient->sendeEncrypted( &len, 1 );
+		klient->sendeEncrypted( status, len );
+		unlock();
+	}
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::accountNameChange( int account, const char *name )
+{
+	if( empfangen )
+		return 0;
+	char len = (char)( name ? textLength( name ) : 0 );
+	if( len )
+	{
+		lock();
+		klient->sendeEncrypted( "\7", 1 );
+		klient->sendeEncrypted( (char*)&account, 4 );
+		klient->sendeEncrypted( &len, 1 );
+		klient->sendeEncrypted( name, len );
+		unlock();
+	}
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::keinFreundMehr( int account )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x8", 1 );
+	klient->sendeEncrypted( (char*)&account, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::freundesAnfrage( int vonAccount )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x9", 1 );
+	klient->sendeEncrypted( (char*)&vonAccount, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::neuerFreund( int account )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\xA", 1 );
+	klient->sendeEncrypted( (char*)&account, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::freundesAnfrageAbgelehnt( int account )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\xB", 1 );
+	klient->sendeEncrypted( (char*)&account, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::einladungZumChatroom( int vonAccount, int chatroomId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\xC", 1 );
+	klient->sendeEncrypted( (char*)&vonAccount, 4 );
+	klient->sendeEncrypted( (char*)&chatroomId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::einladungZumChatroomAbgelehnt( int account, int chatroomId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\xD", 1 );
+	klient->sendeEncrypted( (char*)&account, 4 );
+	klient->sendeEncrypted( (char*)&chatroomId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::spielerBetrittChatroom( int chatroomId, int account )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\xE", 1 );
+	klient->sendeEncrypted( (char*)&chatroomId, 4 );
+	klient->sendeEncrypted( (char*)&account, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::chatroomNachricht( int chatroomId, int vonAccount, const char *nachricht )
+{
+	if( empfangen )
+		return 0;
+	char len = (char)( nachricht ? textLength( nachricht ) : 0);
+	if( len )
+	{
+		lock();
+		klient->sendeEncrypted( "\xF", 1 );
+		klient->sendeEncrypted( (char*)&chatroomId, 4 );
+		klient->sendeEncrypted( (char*)&vonAccount, 4 );
+		klient->sendeEncrypted( &len, 1 );
+		klient->sendeEncrypted( nachricht, len );
+		unlock();
+	}
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::spielerLeavesChatroom( int chatroomId, int accountId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x10", 1 );
+	klient->sendeEncrypted( (char*)&chatroomId, 4 );
+	klient->sendeEncrypted( (char*)&accountId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::freunde( char anzahl, Array< int > *zAccountId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x11", 1 );
+	klient->sendeEncrypted( &anzahl, 1 );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int accId = zAccountId->get( i );
+		klient->sendeEncrypted( (char*)&accId, 4 );
+	}
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::spielerImChatroom( int chatroomId, char anzahl, Array< int > *zAccountId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x12", 1 );
+	klient->sendeEncrypted( (char*)&chatroomId, 4 );
+	klient->sendeEncrypted( &anzahl, 1 );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int accId = zAccountId->get( i );
+		klient->sendeEncrypted( (char*)&accId, 4 );
+	}
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::freundOnline( int accountId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x13", 1 );
+	klient->sendeEncrypted( (char*)&accountId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::freundOffline( int accountId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x14", 1 );
+	klient->sendeEncrypted( (char*)&accountId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::chatroomAdmin( int chatroomId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x15", 1 );
+	klient->sendeEncrypted( (char*)&chatroomId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::chatroomKick( int chatroomId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x16", 1 );
+	klient->sendeEncrypted( (char*)&chatroomId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::spielerBertittGruppe( int accountId, int gruppeId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x17", 1 );
+	klient->sendeEncrypted( (char*)&accountId, 4 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::spielerLeavesGruppe( int accountId, int gruppeId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x18", 1 );
+	klient->sendeEncrypted( (char*)&accountId, 4 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::gruppeNachricht( int gruppeId, char *nachricht )
+{
+	if( empfangen )
+		return 0;
+	char len = (char)textLength( nachricht );
+	if( !len )
+		return 1;
+	lock();
+	klient->sendeEncrypted( "\x19", 1 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	klient->sendeEncrypted( &len, 1 );
+	klient->sendeEncrypted( nachricht, len );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::gruppeAnmelden( int gruppeId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x1A", 1 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::gruppeAbmelden( int gruppeId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x1B", 1 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::gruppeSpielStarten( int gruppeId, bool starten )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x1C", 1 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	if( starten )
+		klient->sendeEncrypted( "\1", 1 );
+	else
+		klient->sendeEncrypted( "\0", 1 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::setGruppeAdmin( int gruppeId, int adminId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x1E", 1 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	klient->sendeEncrypted( (char*)&adminId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::kickAusGruppe( int gruppeId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x1D", 1 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::gruppeEinladungAbgelehnt( int gruppeId, int accountId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x1F", 1 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	klient->sendeEncrypted( (char*)&accountId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::spielServerVerbindungsAnfrage( unsigned short port, unsigned char *ip )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x20", 1 );
+	klient->sendeEncrypted( (char*)&port, 2 );
+	klient->sendeEncrypted( (char*)ip, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::gruppeEinladungAbgebrochen( int gruppeId, int accountId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x21", 1 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	klient->sendeEncrypted( (char*)&accountId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::gruppeEinladungNeu( int gruppeId, int accountId )
+{
+	if( empfangen )
+		return 0;
+	lock();
+	klient->sendeEncrypted( "\x22", 1 );
+	klient->sendeEncrypted( (char*)&gruppeId, 4 );
+	klient->sendeEncrypted( (char*)&accountId, 4 );
+	unlock();
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::errorZuKlient( const char *nachricht ) // sendet eine Fehlernachricht zum Klient
+{
+	char len = (char)textLength( nachricht );
+	if( len )
+	{
+		lock();
+		klient->sendeEncrypted( "\3", 1 );
+		klient->sendeEncrypted( &len, 1 );
+		klient->sendeEncrypted( nachricht, len );
+		unlock();
+	}
+	cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+	cs->addGesendet( klient->getUploadBytes( 1 ) );
+	return 1;
+}
+
+bool CSKlient::keepAlive() // erhält die Verbindung aufrecht
+{
+	char res = 0;
+	lock();
+	klient->sendeEncrypted( "\x23", 1 );
+	klient->getNachrichtEncrypted( &res, 1 );
+	unlock();
+	return res == 1;
+}
+
+void CSKlient::trenne()
+{
+	klient->trenne();
+}
+
+// constant
+int CSKlient::getKlientNummer() const
+{
+	return klientNummer;
+}
+
+int CSKlient::getAccountId() const
+{
+	return accountId;
+}
+
+bool CSKlient::istEmpfang() const
+{
+	return empfangen;
+}
+
+// Reference Counting
+CSKlient *CSKlient::getThis()
+{
+	ref++;
+	return this;
+}
+
+CSKlient *CSKlient::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der MSGWeiterleitung Klasse aus ChatServer.h
+// Konstruktor
+MSGWeiterleitung::MSGWeiterleitung( ChatServer *cs )
+{
+	klient = 0;
+	this->cs = cs;
+	letzterFehler = new Text( "" );
+}
+
+// Destruktor
+MSGWeiterleitung::~MSGWeiterleitung()
+{
+	if( klient )
+	{
+		klient->trenne();
+		klient->release();
+	}
+	letzterFehler->release();
+	cs->release();
+}
+
+// nicht constant
+bool MSGWeiterleitung::kickKlient( int accountId )
+{
+	bool ret = 1;
+	int server = cs->zDB()->getChatServerId( accountId );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( accountId );
+		if( klient )
+		{
+			ret = klient->kick();
+			klient->trenne();
+		}
+		ret = ret & cs->removeAccount( accountId );
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\1", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account ist nicht erreichbar" );
+	return ret;
+}
+
+bool MSGWeiterleitung::accountOnline( int accountId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = cs->zDB()->getAccountOnlineFreunde( accountId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		int server = cs->zDB()->getChatServerId( account );
+		if( server == cs->getId() )
+		{
+			CSKlient *klient = cs->zSendeKlient( account );
+			if( klient )
+				ret = ret & klient->freundOnline( accountId );
+			else
+				ret = 0;
+		}
+		else
+		{
+			char *ip = 0;
+			unsigned short port = 0;
+			ret = ret & cs->zDB()->getChatServerIpPort( server, &port, &ip );
+			if( ip )
+			{
+				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 );
+				ret = ret & klient->sendeEncrypted( "\5\2", 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->getNachrichtEncrypted( &res, 1 );
+				}
+				ret = (char)ret & res;
+				cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+				cs->addGesendet( klient->getUploadBytes( 1 ) );
+				klient->trenne();
+				klient = klient->release();
+			}
+			delete[]ip;
+		}
+	}
+	accId->release();
+	if( !ret )
+		letzterFehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::accountOffline( int accountId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = cs->zDB()->getAccountOnlineFreunde( accountId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		int server = cs->zDB()->getChatServerId( account );
+		if( server == cs->getId() )
+		{
+			CSKlient *klient = cs->zSendeKlient( account );
+			if( klient )
+				ret = ret & klient->freundOffline( accountId );
+			else
+				ret = 0;
+		}
+		else
+		{
+			char *ip = 0;
+			unsigned short port = 0;
+			ret = ret & cs->zDB()->getChatServerIpPort( server, &port, &ip );
+			if( ip )
+			{
+				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 );
+				ret = ret & klient->sendeEncrypted( "\5\3", 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->getNachrichtEncrypted( &res, 1 );
+				}
+				ret = (char)ret & res;
+				cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+				cs->addGesendet( klient->getUploadBytes( 1 ) );
+				klient->trenne();
+				klient = klient->release();
+			}
+			delete[]ip;
+		}
+	}
+	accId->release();
+	if( !ret )
+		letzterFehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::chatNachricht( int vonAccount, int zuAccount, const char *nachricht )
+{
+	bool ret = 1;
+	char len = (char)textLength( nachricht );
+	if( !len )
+		return 1;
+	int server = cs->zDB()->getChatServerId( zuAccount );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( zuAccount );
+		if( klient )
+			ret = klient->nachricht( vonAccount, nachricht );
+		else
+			ret = 0;
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\4", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( (char*)&res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&vonAccount, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&zuAccount, 4 );
+				ret = ret & klient->sendeEncrypted( &len, 1 );
+				ret = ret & klient->sendeEncrypted( (char*)nachricht, len );
+				ret = ret & klient->getNachrichtEncrypted( (char*)&res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account konnte nicht erreicht werden. Die Nachricht wird zugestellt, sobald es möglich ist." );
+	return ret;
+}
+
+bool MSGWeiterleitung::accountStatusChange( int accountId, const char *status )
+{
+	bool ret = 1;
+	char len = (char)textLength( status );
+	if( !len )
+		return 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = cs->zDB()->getAccountOnlineFreunde( accountId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		int server = cs->zDB()->getChatServerId( account );
+		if( server == cs->getId() )
+		{
+			CSKlient *klient = cs->zSendeKlient( account );
+			if( klient )
+				ret = ret & klient->accountStatusChange( accountId, status );
+			else
+				ret = 0;
+		}
+		else
+		{
+			char *ip = 0;
+			unsigned short port = 0;
+			ret = ret & cs->zDB()->getChatServerIpPort( server, &port, &ip );
+			if( ip )
+			{
+				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 );
+				ret = ret & klient->sendeEncrypted( "\5\6", 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*)&len, 1 );
+					ret = ret & klient->sendeEncrypted( (char*)status, len );
+					ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+				}
+				ret = (char)ret & res;
+				cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+				cs->addGesendet( klient->getUploadBytes( 1 ) );
+				klient->trenne();
+				klient = klient->release();
+			}
+			delete[]ip;
+		}
+	}
+	accId->release();
+	if( !ret )
+		letzterFehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::accountNameChange( int accountId, const char *name )
+{
+	bool ret = 1;
+	char len = (char)textLength( name );
+	if( !name )
+		return 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = cs->zDB()->getAccountOnlineFreunde( accountId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		int server = cs->zDB()->getChatServerId( account );
+		if( server == cs->getId() )
+		{
+			CSKlient *klient = cs->zSendeKlient( account );
+			if( klient )
+				ret = ret & klient->accountNameChange( accountId, name );
+			else
+				ret = 0;
+		}
+		else
+		{
+			char *ip = 0;
+			unsigned short port = 0;
+			ret = ret & cs->zDB()->getChatServerIpPort( server, &port, &ip );
+			if( ip )
+			{
+				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 );
+				ret = ret & klient->sendeEncrypted( "\5\7", 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*)&len, 1 );
+					ret = ret & klient->sendeEncrypted( (char*)name, len );
+					ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+				}
+				ret = (char)ret & res;
+				cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+				cs->addGesendet( klient->getUploadBytes( 1 ) );
+				klient->trenne();
+				klient = klient->release();
+			}
+			delete[]ip;
+		}
+	}
+	accId->release();
+	if( !ret )
+		letzterFehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::accountKeinFreundMehr( int accountId, int zielAccountId )
+{
+	bool ret = 1;
+	int server = cs->zDB()->getChatServerId( zielAccountId );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( zielAccountId );
+		if( klient )
+			ret = ret & klient->keinFreundMehr( accountId );
+		else
+			ret = 0;
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\x8", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&zielAccountId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account konnte nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::freundesAnfrage( int vonAccountId, int zuAccountId )
+{
+	bool ret = 1;
+	int server = cs->zDB()->getChatServerId( zuAccountId );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( zuAccountId );
+		if( klient )
+			ret = ret & klient->freundesAnfrage( vonAccountId );
+		else
+			ret = 0;
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\x9", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&vonAccountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&zuAccountId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account konnte nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::neuerFreund( int accountId, int zuAccountId )
+{
+	bool ret = 1;
+	int server = cs->zDB()->getChatServerId( zuAccountId );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( zuAccountId );
+		if( klient )
+			ret = ret & klient->neuerFreund( accountId );
+		else
+			ret = 0;
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\xA", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&zuAccountId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account konnte nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::einladungZumChatroom( int vonAccountId, int zuAccountId, int chatroomId )
+{
+	bool ret = 1;
+	int server = cs->zDB()->getChatServerId( zuAccountId );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( zuAccountId );
+		if( klient )
+			ret = ret & klient->einladungZumChatroom( vonAccountId, chatroomId );
+		else
+			ret = 0;
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\xB", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&vonAccountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&zuAccountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&chatroomId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account konnte nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::spielerBetrittChatroom( int accountId, int chatroomId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = cs->zDB()->getChatroomAccount( chatroomId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		if( account == accountId )
+			continue;
+		int server = cs->zDB()->getChatServerId( account );
+		if( server == cs->getId() )
+		{
+			CSKlient *klient = cs->zSendeKlient( account );
+			if( klient )
+				ret = ret & klient->spielerBetrittChatroom( chatroomId, accountId );
+			else
+				ret = 0;
+		}
+		else
+		{
+			char *ip = 0;
+			unsigned short port = 0;
+			ret = ret & cs->zDB()->getChatServerIpPort( server, &port, &ip );
+			if( ip )
+			{
+				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 );
+				ret = ret & klient->sendeEncrypted( "\5\xC", 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;
+				cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+				cs->addGesendet( klient->getUploadBytes( 1 ) );
+				klient->trenne();
+				klient = klient->release();
+			}
+			delete[]ip;
+		}
+	}
+	accId->release();
+	if( !ret )
+		letzterFehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::chatroomNachricht( int vonAccount, const char *nachricht, int chatroomId )
+{
+	bool ret = 1;
+	char len = (char)textLength( nachricht );
+	if( !len )
+		return 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = cs->zDB()->getChatroomAccount( chatroomId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		int server = cs->zDB()->getChatServerId( account );
+		if( server == cs->getId() )
+		{
+			CSKlient *klient = cs->zSendeKlient( account );
+			if( klient )
+				ret = ret & klient->chatroomNachricht( chatroomId, vonAccount, nachricht );
+			else
+				ret = 0;
+		}
+		else
+		{
+			char *ip = 0;
+			unsigned short port = 0;
+			ret = ret & cs->zDB()->getChatServerIpPort( server, &port, &ip );
+			if( ip )
+			{
+				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 );
+				ret = ret & klient->sendeEncrypted( "\5\xD", 2 );
+				char res = 0;
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+				if( res )
+				{
+					ret = ret & klient->sendeEncrypted( (char*)&vonAccount, 4 );
+					ret = ret & klient->sendeEncrypted( (char*)&account, 4 );
+					ret = ret & klient->sendeEncrypted( (char*)&chatroomId, 4 );
+					ret = ret & klient->sendeEncrypted( &len, 1 );
+					ret = ret & klient->sendeEncrypted( (char*)nachricht, len );
+					ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+				}
+				ret = (char)ret & res;
+				cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+				cs->addGesendet( klient->getUploadBytes( 1 ) );
+				klient->trenne();
+				klient = klient->release();
+			}
+			delete[]ip;
+		}
+	}
+	accId->release();
+	if( !ret )
+		letzterFehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::spielerLeavestChatroom( int accountId, int chatroomId )
+{
+	bool ret = 1;
+	Array< int > *accId = new Array< int >();
+	int anzahl = cs->zDB()->getChatroomAccount( chatroomId, accId );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		int account = accId->get( i );
+		int server = cs->zDB()->getChatServerId( account );
+		if( server == cs->getId() )
+		{
+			CSKlient *klient = cs->zSendeKlient( account );
+			if( klient )
+				ret = ret & klient->spielerLeavesChatroom( chatroomId, accountId );
+			else
+				ret = 0;
+		}
+		else
+		{
+			char *ip = 0;
+			unsigned short port = 0;
+			ret = ret & cs->zDB()->getChatServerIpPort( server, &port, &ip );
+			if( ip )
+			{
+				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 );
+				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;
+				cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+				cs->addGesendet( klient->getUploadBytes( 1 ) );
+				klient->trenne();
+				klient = klient->release();
+			}
+			delete[]ip;
+		}
+	}
+	accId->release();
+	if( !ret )
+		letzterFehler->setText( "Einer oder mehr Accounts konnen nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::freundEinladungAbgelehnt( int accountId, int zuAccountId )
+{
+	bool ret = 1;
+	int server = cs->zDB()->getChatServerId( zuAccountId );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( zuAccountId );
+		if( klient )
+			ret = ret & klient->freundesAnfrageAbgelehnt( accountId );
+		else
+			ret = 0;
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\xF", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&zuAccountId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account konnte nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::chatroomEinladungAbgelehnt( int accountId, int chatroomId, int zuAccountId )
+{
+	bool ret = 1;
+	int server = cs->zDB()->getChatServerId( zuAccountId );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( zuAccountId );
+		if( klient )
+			ret = ret & klient->einladungZumChatroomAbgelehnt( accountId, chatroomId );
+		else
+			ret = 0;
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\x10", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&zuAccountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&chatroomId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account konnte nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::fehler( int zuAccountId, const char *fehler )
+{
+	bool ret = 1;
+	char len = (char)textLength( fehler );
+	if( !len )
+		return 1;
+	int server = cs->zDB()->getChatServerId( zuAccountId );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( zuAccountId );
+		if( klient )
+			ret = ret & klient->errorZuKlient( fehler );
+		else
+			ret = 0;
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\x11", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&zuAccountId, 4 );
+				ret = ret & klient->sendeEncrypted( &len, 1 );
+				ret = ret & klient->sendeEncrypted( (char*)&fehler, len );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account konnte nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::chatroomAdmin( int chatroomId, int zuAccountId )
+{
+	bool ret = 1;
+	int server = cs->zDB()->getChatServerId( zuAccountId );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( zuAccountId );
+		if( klient )
+			ret = ret & klient->chatroomAdmin( chatroomId );
+		else
+			ret = 0;
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\x12", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&zuAccountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&chatroomId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account konnte nicht erreicht werden" );
+	return ret;
+}
+
+bool MSGWeiterleitung::chatroomKick( int chatroomId, int accountId )
+{
+	bool ret = 1;
+	int server = cs->zDB()->getChatServerId( accountId );
+	if( server == cs->getId() )
+	{
+		CSKlient *klient = cs->zSendeKlient( accountId );
+		if( klient )
+			ret = ret & klient->chatroomKick( chatroomId );
+		else
+			ret = 0;
+	}
+	else
+	{
+		char *ip = 0;
+		unsigned short port = 0;
+		ret = cs->zDB()->getChatServerIpPort( server, &port, &ip );
+		if( ip )
+		{
+			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 );
+			ret = ret & klient->sendeEncrypted( "\5\x13", 2 );
+			char res = 0;
+			ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			if( res )
+			{
+				ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
+				ret = ret & klient->sendeEncrypted( (char*)&chatroomId, 4 );
+				ret = ret & klient->getNachrichtEncrypted( &res, 1 );
+			}
+			ret = (char)ret & res;
+			cs->addEmpfangen( klient->getDownloadBytes( 1 ) );
+			cs->addGesendet( klient->getUploadBytes( 1 ) );
+			klient->trenne();
+			klient = klient->release();
+		}
+		delete[]ip;
+	}
+	if( !ret )
+		letzterFehler->setText( "Der Account konnte nicht erreicht werden" );
+	return ret;
+}
+
+// constant
+const char *MSGWeiterleitung::getLetzterFehler()
+{
+	return letzterFehler->getText();
+}

+ 189 - 0
ChatServer/ChatServer.h

@@ -0,0 +1,189 @@
+#ifndef ChatServer_H
+#define ChatServer_H
+
+#include <Server.h>
+#include <Thread.h>
+#include <Datei.h>
+#include <Text.h>
+#include <InitDatei.h>
+#include "Datenbank.h"
+#include <Klient.h>
+
+using namespace Framework;
+using namespace Network;
+
+class CSKlient;
+class KlientArray;
+
+class ChatServer : public Thread
+{
+private:
+	Server *server;
+	Server *aServer;
+	InitDatei *ini;
+	CSDatenbank *db;
+	CRITICAL_SECTION cs;
+	RCArray< CSKlient > *klients;
+	Text *fehler;
+	int klientAnzahl;
+	int id;
+	bool nichtPausiert;
+	int empfangen;
+	int gesendet;
+	bool end;
+	int ref;
+
+public:
+	// Konstruktor 
+	ChatServer( InitDatei *zIni );
+	// Destruktor 
+	virtual ~ChatServer();
+	// nicht constant 
+	void runn();
+	void thread();
+	void close();
+	bool serverStarten();
+	bool serverPause();
+	bool serverFortsetzen();
+	bool serverBeenden();
+	bool setMaxKlients( int mc );
+	bool absturzKlient( int klientId );
+	bool removeAccount( int accId );
+	bool removeKlient( int klientId );
+	bool removeKlient( CSKlient *zKlient );
+	void addGesendet( int bytes );
+	void addEmpfangen( int bytes );
+	int getKlientStatus( int klientNummer, CSKlient *zKlient );
+	CSKlient *zSendeKlient( int accountId );
+	// conatant 
+	bool istAn() const;
+	Server *zServer() const;
+	CSDatenbank *zDB() const;
+	bool hatClients() const;
+	int getId() const;
+	char *getLetzterFehler() const;
+	// Reference Counting
+	ChatServer *getThis();
+	ChatServer *release();
+};
+
+class CSAKlient : public Thread
+{
+private:
+	SKlient *klient;
+	Text *name;
+	Text *passwort;
+	int adminId;
+	ChatServer *cs;
+
+public:
+	// Konstruktor 
+	CSAKlient( SKlient *klient, ChatServer *cs );
+	// Destruktor 
+	virtual ~CSAKlient();
+	// nicht constant
+	void thread();
+	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum AKlient
+};
+
+class CSKlient : public Thread
+{
+private:
+	SKlient *klient;
+	unsigned int klientNummer;
+	unsigned int accountId;
+	ChatServer *cs;
+	CRITICAL_SECTION ts;
+	bool empfangen;
+	int ref;
+
+public:
+	// Konstruktor 
+	CSKlient( SKlient *klient, ChatServer *cs );
+	// Destruktor 
+	virtual ~CSKlient();
+	// nicht constant 
+	void lock();
+	void unlock();
+	void absturz();
+	void thread();
+	bool kick();
+	bool nachricht( int vonAccount, const char *txt );
+	bool gruppeEinladung( int vonAccount, int gruppeId );
+	bool accountStatusChange( int account, const char *status );
+	bool accountNameChange( int account, const char *name );
+	bool keinFreundMehr( int account );
+	bool freundesAnfrage( int vonAccount );
+	bool neuerFreund( int account );
+	bool freundesAnfrageAbgelehnt( int account );
+	bool einladungZumChatroom( int vonAccount, int chatroomId );
+	bool einladungZumChatroomAbgelehnt( int account, int chatroomId );
+	bool spielerBetrittChatroom( int chatroomId, int account );
+	bool chatroomNachricht( int chatroomId, int vonAccount, const char *nachricht );
+	bool spielerLeavesChatroom( int chatroomId, int accountId );
+	bool freunde( char anzahl, Array< int > *zAccountId );
+	bool spielerImChatroom( int chatroomId, char anzahl, Array< int > *zAccountId );
+	bool freundOnline( int accountId );
+	bool freundOffline( int accountId );
+	bool chatroomAdmin( int chatroomId );
+	bool chatroomKick( int chatroomId );
+	bool spielerBertittGruppe( int accountId, int gruppeId );
+	bool spielerLeavesGruppe( int accountId, int gruppeId );
+	bool gruppeNachricht( int gruppeId, char *nachricht );
+	bool gruppeAnmelden( int gruppeId );
+	bool gruppeAbmelden( int gruppeID );
+	bool gruppeSpielStarten( int gruppeId, bool starten );
+	bool setGruppeAdmin( int gruppeId, int adminId );
+	bool kickAusGruppe( int gruppeId );
+	bool gruppeEinladungAbgelehnt( int gruppeId, int accountId );
+	bool spielServerVerbindungsAnfrage( unsigned short port, unsigned char *ip );
+	bool gruppeEinladungAbgebrochen( int gruppeId, int accountId );
+	bool gruppeEinladungNeu( int gruppeId, int accountId );
+	bool errorZuKlient( const char *nachricht ); // sendet eine Fehlernachricht zum Klient
+	bool keepAlive(); // erhält die Verbindung aufrecht
+	void trenne();
+	// constant
+	int getKlientNummer() const;
+	int getAccountId() const;
+	bool istEmpfang() const;
+	// Reference Counting
+	CSKlient *getThis();
+	CSKlient *release();
+};
+
+class MSGWeiterleitung
+{
+private:
+	ChatServer *cs;
+	Klient *klient;
+	Text *letzterFehler;
+
+public:
+	// Konstruktor
+	MSGWeiterleitung( ChatServer *cs );
+	// Destruktor
+	~MSGWeiterleitung();
+	// nicht constant
+	bool kickKlient( int accountId );
+	bool accountOnline( int accountId );
+	bool accountOffline( int accountId );
+	bool chatNachricht( int vonAccount, int zuAccount, const char *nachricht );
+	bool accountStatusChange( int accountId, const char *status );
+	bool accountNameChange( int accountId, const char *name );
+	bool accountKeinFreundMehr( int accountId, int zielAccountId );
+	bool freundesAnfrage( int vonAccountId, int zuAccountId );
+	bool neuerFreund( int accountId, int zuAccountId );
+	bool einladungZumChatroom( int vonAccountId, int zuAccountId, int chatroomId );
+	bool spielerBetrittChatroom( int accountId, int chatroomId );
+	bool chatroomNachricht( int vonAccount, const char *nachricht, int chatroomId );
+	bool spielerLeavestChatroom( int accountId, int chatroomId );
+	bool freundEinladungAbgelehnt( int accountId, int zuAccountId );
+	bool chatroomEinladungAbgelehnt( int accountId, int chatroomId, int zuAccountId );
+	bool chatroomAdmin( int chatroomId, int zuAccountId );
+	bool chatroomKick( int chatroomId, int accountId );
+	bool fehler( int zuAccountId, const char *fehler );
+	// constant
+	const char *getLetzterFehler();
+};
+
+#endif

+ 106 - 0
ChatServer/ChatServer.vcxproj

@@ -0,0 +1,106 @@
+<?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|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x86">
+      <Configuration>Debug</Configuration>
+      <Platform>x86</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x86">
+      <Configuration>Release</Configuration>
+      <Platform>x86</Platform>
+    </ProjectConfiguration>
+    <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>{d2d06294-33ce-4552-a59c-3f691ec2d7f1}</ProjectGuid>
+    <Keyword>Linux</Keyword>
+    <RootNamespace>ChatServer</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|ARM'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+  </PropertyGroup>
+  <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;..\..\..\..\Allgemein\Network\Network;..\..\..\..\Allgemein\sql\sql;../../../Framework/Debug;../../../Network/Debug;../../../sql/Debug;$(IncludePath)</IncludePath>
+    <TargetExt />
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/Release</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;..\..\..\..\Allgemein\Network\Network;..\..\..\..\Allgemein\sql\sql;../../../Framework/Release;../../../Network/Release;../../../sql/Release;$(IncludePath)</IncludePath>
+    <TargetExt />
+  </PropertyGroup>
+  <ItemGroup>
+    <ClCompile Include="ChatServer.cpp" />
+    <ClCompile Include="Datenbank.cpp" />
+    <ClCompile Include="main.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="ChatServer.h" />
+    <ClInclude Include="Datenbank.h" />
+  </ItemGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Link>
+      <LibraryDependencies>dbgFramework;dbgNetwork;dbgSQL;pq;pthread</LibraryDependencies>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/Debug/bin/x64/debug;$(RemoteRootDir)/Network/Debug/bin/x64/debug;$(RemoteRootDir)/Framework/Debug/bin/x64/debug;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </Link>
+    <ClCompile>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Link>
+      <LibraryDependencies>Framework;Network;SQL;pq;pthread</LibraryDependencies>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/Release/bin/x64/release;$(RemoteRootDir)/Network/Release/bin/x64/release;$(RemoteRootDir)/Framework/Release/bin/x64/release;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </Link>
+    <ClCompile>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>

+ 30 - 0
ChatServer/ChatServer.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="Quelldateien">
+      <UniqueIdentifier>{8026afd2-4f3a-4d9d-8acd-d2cb3ea11baf}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Headertateien">
+      <UniqueIdentifier>{2b5d18e1-c665-4053-a777-50d0c9c01a1e}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="ChatServer.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Datenbank.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="main.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="ChatServer.h">
+      <Filter>Headertateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Datenbank.h">
+      <Filter>Headertateien</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>

+ 830 - 0
ChatServer/Datenbank.cpp

@@ -0,0 +1,830 @@
+#include "Datenbank.h"
+
+// Inhalt der CSDatenbank Klasse aus Datenbank.h
+// Konstruktor
+CSDatenbank::CSDatenbank( InitDatei *zIni )
+{
+	if( !zIni->wertExistiert( "DBBenutzer" ) )
+		zIni->addWert( "DBBenutzer", "chatserveru" );
+	if( !zIni->wertExistiert( "DBPasswort" ) )
+		zIni->addWert( "DBPasswort", "LTChatServerPW" );
+	if( !zIni->wertExistiert( "DBName" ) )
+		zIni->addWert( "DBName", "lenck_tech_db" );
+	if( !zIni->wertExistiert( "DBIP" ) )
+		zIni->addWert( "DBIP", "127.0.0.1" );
+	if( !zIni->wertExistiert( "DBPort" ) )
+		zIni->addWert( "DBPort", "5432" );
+	datenbank = new Datenbank( zIni->zWert( "DBBenutzer" )->getText(), zIni->zWert( "DBPasswort" )->getText(),
+							   zIni->zWert( "DBName" )->getText(), zIni->zWert( "DBIP" )->getText(),
+							   (unsigned short)TextZuInt( zIni->zWert( "DBPort" )->getText(), 10 ) );
+	InitializeCriticalSection( &cs );
+	ref = 1;
+}
+
+// Destruktor
+CSDatenbank::~CSDatenbank()
+{
+	datenbank->release();
+	DeleteCriticalSection( &cs );
+}
+
+// nicht constant
+void CSDatenbank::lock()
+{
+	EnterCriticalSection( &cs );
+}
+
+void CSDatenbank::unlock()
+{
+	LeaveCriticalSection( &cs );
+}
+
+int CSDatenbank::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 CSDatenbank::adminHatRecht( int id, int recht )
+{
+	Text *befehl = new Text( "SELECT * FROM benutzer_rechte WHERE benutzer_id = " );
+	befehl->append( id );
+	befehl->append( " AND rechte_id = " );
+	befehl->append( recht );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	int ret = datenbank->getZeilenAnzahl();
+	unlock();
+	befehl->release();
+	return ret != 0;
+}
+
+bool CSDatenbank::proveKlient( int num, int sNum )
+{
+	Text *befehl = new Text( "SELECT * FROM server_chat_clients WHERE server_chat_id = " );
+	befehl->append( sNum );
+	befehl->append( " AND client_id = " );
+	befehl->append( num );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	bool ret = 0;
+	if( res.zeilenAnzahl == 1 )
+		ret = 1;
+	res.destroy();
+	return ret;
+}
+
+Text *CSDatenbank::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;
+}
+
+void CSDatenbank::unregisterKlient( int num, int sNum )
+{
+	Text *befehl = new Text( "DELETE FROM server_chat_clients WHERE client_id = " );
+	befehl->append( num );
+	befehl->append( " AND server_chat_id = " );
+	befehl->append( sNum );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	int za = datenbank->getZeilenAnzahl();
+	unlock();
+	if( za == 1 )
+	{
+		befehl->setText( "UPDATE server_chat SET clients = clients - 1 WHERE id = " );
+		befehl->append( sNum );
+		lock();
+		datenbank->befehl( befehl->getText() );
+		unlock();
+	}
+	befehl->release();
+}
+
+bool CSDatenbank::serverAnmelden( InitDatei *zIni )
+{
+	if( !zIni->wertExistiert( "ServerId" ) )
+		zIni->addWert( "ServerId", "0" );
+	if( !zIni->wertExistiert( "ServerName" ) )
+		zIni->addWert( "ServerName", "Name" );
+	if( !zIni->wertExistiert( "ServerPort" ) )
+		zIni->addWert( "ServerPort", "49144" );
+	if( !zIni->wertExistiert( "ServerIP" ) )
+		zIni->addWert( "ServerIP", "127.0.0.1" );
+	if( !zIni->wertExistiert( "AdminServerPort" ) )
+		zIni->addWert( "AdminServerPort", "49143" );
+	if( !zIni->wertExistiert( "Aktiv" ) )
+		zIni->addWert( "Aktiv", "FALSE" );
+	if( !zIni->wertExistiert( "MaxClients" ) )
+		zIni->addWert( "MaxClients", "50" );
+	bool insert = 0;
+	int id = *zIni->zWert( "ServerId" );
+	if( id )
+	{
+		lock();
+		if( !datenbank->befehl( Text( "SELECT id FROM server_chat WHERE id = " ) += id ) )
+		{
+			unlock();
+			return 0;
+		}
+		int anz = datenbank->getZeilenAnzahl();
+		unlock();
+		insert = anz == 0;
+		if( !insert )
+		{
+			lock();
+			if( !datenbank->befehl( Text( "SELECT id FROM server_chat WHERE server_status_id = 1 AND id = " ) += id ) )
+			{
+				unlock();
+				return 0;
+			}
+			int anz = datenbank->getZeilenAnzahl();
+			unlock();
+			if( !anz ) // Server läuft bereits
+				return 0;
+		}
+	}
+	if( insert || !id )
+	{ // Neuer Eintrag in Tabelle server_chat
+		Text *befehl = new Text( "INSERT INTO server_chat( " );
+		if( id )
+			*befehl += "id, ";
+		*befehl += "name, ip, port, admin_port, server_status_id, max_clients ) VALUES( ";
+		if( id )
+		{
+			*befehl += id;
+			*befehl += ", ";
+		}
+		*befehl += "'";
+		*befehl += zIni->zWert( "ServerName" )->getText();
+		*befehl += "', '";
+		*befehl += zIni->zWert( "ServerIP" )->getText();
+		*befehl += "', ";
+		*befehl += zIni->zWert( "ServerPort" )->getText();
+		*befehl += ", ";
+		*befehl += zIni->zWert( "AdminServerPort" )->getText();
+		*befehl += ", 1, ";
+		*befehl += zIni->zWert( "MaxClients" )->getText();
+		*befehl += " ) RETURNING id";
+		lock();
+		if( !datenbank->befehl( *befehl ) )
+		{
+			unlock();
+			befehl->release();
+			return 0;
+		}
+		Result res = datenbank->getResult();
+		unlock();
+		befehl->release();
+		if( !res.zeilenAnzahl )
+		{
+			res.destroy();
+			return 0;
+		}
+		zIni->setWert( "ServerId", res.values[ 0 ] );
+		return 1;
+	}
+	else
+	{ // Alten Eintrag aus Tabelle server_chat ändern
+		Text *befehl = new Text( "UPDATE server_chat SET name = '" );
+		*befehl += zIni->zWert( "ServerName" )->getText();
+		*befehl += "', port = ";
+		*befehl += zIni->zWert( "ServerPort" )->getText();
+		*befehl += ", ip = '";
+		*befehl += zIni->zWert( "ServerIP" )->getText();
+		*befehl += "', max_clients = ";
+		*befehl += zIni->zWert( "MaxClients" )->getText();
+		*befehl += ", admin_port = ";
+		*befehl += zIni->zWert( "AdminServerPort" )->getText();
+		*befehl += " WHERE id = ";
+		*befehl += id;
+		lock();
+		bool ret = datenbank->befehl( *befehl );
+		unlock();
+		befehl->release();
+		return ret;
+	}
+}
+
+bool CSDatenbank::setServerStatus( int id, int status )
+{
+	Text *befehl = new Text( "UPDATE server_chat SET server_status_id = " );
+	*befehl += status;
+	*befehl += "WHERE id = ";
+	*befehl += id;
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	bool ret = datenbank->getZeilenAnzahl() != 0;
+	unlock();
+	befehl->release();
+	return ret;
+}
+
+bool CSDatenbank::setMaxClients( int id, int maxC )
+{
+	Text *befehl = new Text( "UPDATE server_chat SET max_clients = " );
+	befehl->append( maxC );
+	befehl->append( " WHERE id = " );
+	befehl->append( id );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	bool ret = datenbank->getZeilenAnzahl() > 0;
+	unlock();
+	befehl->release();
+	return ret;
+}
+
+int CSDatenbank::getAdminPort( int id )
+{
+	Text *befehl = new Text( "SELECT admin_port FROM server_chat WHERE id = " );
+	befehl->append( id );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	if( !res.zeilenAnzahl )
+	{
+		res.destroy();
+		return 0;
+	}
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+bool CSDatenbank::serverIstNichtPausiert( int id )
+{
+	Text *befehl = new Text( "SELECT server_status_id FROM server_chat WHERE id = " );
+	befehl->append( id );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	if( !res.zeilenAnzahl )
+	{
+		res.destroy();
+		return 0;
+	}
+	bool ret = (int)res.values[ 0 ] == 3;
+	res.destroy();
+	return ret;
+}
+
+int CSDatenbank::getKlientAccountId( int klientId )
+{
+	Text *befehl = new Text( "SELECT account_id FROM account_clients WHERE client_id = " );
+	befehl->append( klientId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	if( res.zeilenAnzahl )
+	{
+		int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+		res.destroy();
+		return ret;
+	}
+	res.destroy();
+	return 0;
+}
+
+int CSDatenbank::getAccountFreunde( int accountId, Array< int > *fAccountId )
+{
+	Text *befehl = new Text( "SELECT account_id AS freundId FROM freund WHERE freund_account_id = " );
+	befehl->append( accountId );
+	befehl->append( " UNION SELECT freund_account_id AS freundId FROM freund WHERE account_id = " );
+	befehl->append( accountId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	int anzahl = res.zeilenAnzahl;
+	for( int i = 0; i < anzahl; i++ )
+		fAccountId->add( TextZuInt( res.values[ i ].getText(), 10 ), i );
+	res.destroy();
+	return anzahl;
+}
+
+int CSDatenbank::getAccountOnlineFreunde( int accountId, Array< int > *fAccountId )
+{
+	Text *befehl = new Text( "SELECT freund.account_id AS freundId FROM freund, account_clients WHERE freund.freund_account_id = " );
+	befehl->append( accountId );
+	befehl->append( " AND freund.account_id = account_clients.account_id "
+					  "UNION SELECT freund.freund_account_id AS freundId FROM freund, account_clients WHERE freund.account_id = " );
+	befehl->append( accountId );
+	befehl->append( " AND freund.freund_account_id = account_clients.account_id " );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	int anzahl = res.zeilenAnzahl;
+	for( int i = 0; i < anzahl; i++ )
+		fAccountId->add( TextZuInt( res.values[ i ].getText(), 10 ), i );
+	res.destroy();
+	return anzahl;
+}
+
+bool CSDatenbank::accountNameChange( int accountId, const char *name )
+{
+	if( !name )
+		return 1;
+	Text *befehl = new Text( "UPDATE account SET ruf_name = '" );
+	Text n( name );
+	n.ersetzen( "'", "''" );
+	befehl->append( (char*)n );
+	befehl->append( "' WHERE id = " );
+	befehl->append( accountId );
+	bool ret = 0;
+	lock();
+	ret = datenbank->befehl( befehl->getText() );
+	unlock();
+	befehl->release();
+	return ret;
+}
+
+bool CSDatenbank::beendeFreundschaft( int accountId1, int accountId2 )
+{
+	Text *befehl = new Text( "DELETE FROM freund WHERE ( account_id = " );
+	befehl->append( accountId1 );
+	befehl->append( " AND freund_account_id = " );
+	befehl->append( accountId2 );
+	befehl->append( " ) OR ( freund_account_id = " );
+	befehl->append( accountId1 );
+	befehl->append( " AND account_id = " );
+	befehl->append( accountId2 );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		return 0;
+	}
+	unlock();
+	befehl->release();
+	return 1;
+}
+
+bool CSDatenbank::proveFreundschaftsAnfrage( int vonAccountId, int zuAccountId )
+{
+	if( vonAccountId == zuAccountId )
+		return 0;
+	Text *befehl = new Text( "SELECT account_id AS freundId FROM freund WHERE freund_account_id = " );
+	befehl->append( vonAccountId );
+	befehl->append( " AND freund.account_id = " );
+	befehl->append( zuAccountId );
+	befehl->append( "UNION SELECT freund_account_id AS freundId FROM freund WHERE freund_account_id = " );
+	befehl->append( zuAccountId );
+	befehl->append( " AND freund.account_id = " );
+	befehl->append( vonAccountId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	bool ret = res.zeilenAnzahl == 0;
+	res.destroy();
+	return ret;
+}
+
+bool CSDatenbank::saveFreundschaftsAnfrage( int vonAccountId, int zuAccountId )
+{
+	Text *befehl = new Text( "SELECT account_id FROM freund_anfrage WHERE ( account_id = " );
+	befehl->append( vonAccountId );
+	befehl->append( " AND freund_id = " );
+	befehl->append( zuAccountId );
+	befehl->append( " ) OR ( freund_id = " );
+	befehl->append( vonAccountId );
+	befehl->append( " AND account_id = " );
+	befehl->append( zuAccountId );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	Result res = datenbank->getResult();
+	unlock();
+	if( res.zeilenAnzahl )
+	{
+		res.destroy();
+		befehl->release();
+		return 1;
+	}
+	res.destroy();
+	befehl->setText( "INSERT INTO freund_anfrage( account_id, freund_id ) VALUES( " );
+	befehl->append( vonAccountId );
+	befehl->append( ", " );
+	befehl->append( zuAccountId );
+	befehl->append( " )" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	unlock();
+	befehl->release();
+	return 1;
+}
+
+int CSDatenbank::getFreundschaftsAnfragen( int accountId, Array< int > *vonAccountIds )
+{
+	Text *befehl = new Text( "SELECT account_id FROM freund_anfrage WHERE freund_id = " );
+	befehl->append( accountId );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->setText( "DELETE FROM freund_anfrage WHERE freund_id = " );
+	befehl->append( accountId ); lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		res.destroy();
+		return 0;
+	}
+	unlock();
+	befehl->release();
+	int anzahl = res.zeilenAnzahl;
+	for( int i = 0; i < anzahl; i++ )
+		vonAccountIds->set( res.values[ i ], i );
+	res.destroy();
+	return anzahl;
+}
+
+bool CSDatenbank::neueFreundschaft( int accountId1, int accountId2 )
+{
+	Text *befehl = new Text( "INSERT INTO freund VALUES( " );
+	befehl->append( accountId1 );
+	befehl->append( ", " );
+	befehl->append( accountId2 );
+	befehl->append( " )" );
+	lock();
+	bool ret = datenbank->befehl( befehl->getText() );
+	unlock();
+	befehl->release();
+	return ret;
+}
+
+Text *CSDatenbank::getAccountRufName( int accountId )
+{
+	Text *befehl = new Text( "SELECT ruf_name FROM account WHERE id = " );
+	befehl->append( accountId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	Text *ret = new Text( res.values[ 0 ].getText() );
+	res.destroy();
+	return ret;
+}
+
+bool CSDatenbank::accountIstOnline( int accountId )
+{
+	Text *befehl = new Text( "SELECT * FROM account_clients WHERE account_id = " );
+	befehl->append( accountId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	int res = datenbank->getZeilenAnzahl();
+	unlock();
+	befehl->release();
+	return res != 0;
+}
+
+bool CSDatenbank::accountIstImSpiel( int accountId )
+{
+	Text *befehl = new Text( "SELECT b.id FROM spiel_spieler a, spiel b WHERE b.spiel_status_id = 2 "
+							 "AND a.spiel_spieler_status_id = 5 AND a.spiel_id = b.id AND a.account_id = " );
+	befehl->append( accountId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	int res = datenbank->getZeilenAnzahl();
+	unlock();
+	befehl->release();
+	return res != 0;
+}
+
+int CSDatenbank::getChatServerId( int accountId )
+{
+	Text *befehl = new Text( "SELECT server_chat_clients.server_chat_id FROM server_chat_clients, account_clients "
+							 "WHERE server_chat_clients.client_id = account_clients.client_id AND account_clients.account_id = " );
+	befehl->append( accountId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	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 CSDatenbank::getChatServerIpPort( int serverId, unsigned short *port, char **ip )
+{
+	Text *befehl = new Text( "SELECT port, ip FROM server_chat WHERE id = " );
+	befehl->append( serverId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	if( !res.zeilenAnzahl )
+	{
+		res.destroy();
+		return 0;
+	}
+	*port = (unsigned short)TextZuInt( res.values[ 0 ].getText(), 10 );
+	int len = res.values[ 1 ].getLength();
+	char *ipTmp = new char[ len + 1 ];
+	ipTmp[ len ] = 0;
+	int i = 0;
+	for( char *c = res.values[ 1 ].getText(); i < len; c++ )
+	{
+		ipTmp[ i ] = *c;
+		i++;
+	}
+	res.destroy();
+	return 1;
+}
+
+int CSDatenbank::getChatNachrichten( int accountId, Array< int > *vonAccount, RCArray< Text > *nachricht )
+{
+	Text *befehl = new Text( "SELECT von_account_id, nachricht FROM chat_nachricht WHERE zu_account_id = " );
+	befehl->append( accountId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	if( !res.zeilenAnzahl )
+	{
+		befehl->release();
+		res.destroy();
+		return 0;
+	}
+	int ret = res.zeilenAnzahl;
+	for( int i = 0; i < ret; i++ )
+	{
+		vonAccount->add( TextZuInt( res.values[ i * 2 ].getText(), 10 ), i );
+		nachricht->add( new Text( res.values[ i * 2 + 1 ].getText() ), i );
+	}
+	res.destroy();
+	befehl->setText( "DELETE FROM chat_nachricht WHERE zu_account_id = " );
+	befehl->append( accountId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	unlock();
+	befehl->release();
+	return ret;
+}
+
+bool CSDatenbank::speicherChatNachricht( int vonAccount, int zuAccount, const char *nachricht )
+{
+	if( !nachricht )
+		return 1;
+	Text *befehl = new Text( "INSERT INTO chat_nachricht VALUES( " );
+	befehl->append( vonAccount );
+	befehl->append( ", " );
+	befehl->append( zuAccount );
+	befehl->append( ", '" );
+	Text n( nachricht );
+	n.ersetzen( "'", "''" );
+	befehl->append( (char*)n );
+	befehl->append( "' )" );
+	lock();
+	bool ret = datenbank->befehl( befehl->getText() );
+	unlock();
+	befehl->release();
+	return ret;
+}
+
+int CSDatenbank::getChatroomAccount( int chatroomId, Array< int > *accountId )
+{
+	Text *befehl = new Text( "SELECT account_id FROM chatroom_spieler WHERE chatroom_id = " );
+	befehl->append( chatroomId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	if( !res.zeilenAnzahl )
+	{
+		res.destroy();
+		return 0;
+	}
+	int ret = res.zeilenAnzahl;
+	for( int i = 0; i < ret; i++ )
+		accountId->add( TextZuInt( res.values[ i ].getText(), 10 ), i );
+	res.destroy();
+	return ret;
+}
+
+int CSDatenbank::chatroomErstellen( int accountId, const char *name )
+{
+	Text *befehl = new Text( "INSERT INTO chatroom( admin_account_id, name ) VALUES( " );
+	befehl->append( accountId );
+	befehl->append( ", '" );
+	Text n( name );
+	n.ersetzen( "'", "''" );
+	befehl->append( (char*)n );
+	befehl->append( "' ) RETURNING id" );
+	lock();
+	if( !datenbank->befehl( befehl->getText() ) )
+	{
+		unlock();
+		befehl->release();
+		return 0;
+	}
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->setText( "INSERT INTO chatroom_spieler VALUES( ( SELECT id FROM chatroom WHERE name = '" );
+	befehl->append( (char*)n );
+	befehl->append( "' ), " );
+	befehl->append( accountId );
+	befehl->append( " )" );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	unlock();
+	befehl->release();
+	if( !res.zeilenAnzahl )
+	{
+		res.destroy();
+		return 0;
+	}
+	int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+	res.destroy();
+	return ret;
+}
+
+bool CSDatenbank::proveChatroomEinladung( int vonAccount, int zuAccount, int chatroomId )
+{
+	Text *befehl = new Text( "SELECT pruef_chatroom_einladung( " );
+	befehl->append( chatroomId );
+	befehl->append( ", " );
+	befehl->append( vonAccount );
+	befehl->append( ", " );
+	befehl->append( zuAccount );
+	befehl->append( " )" );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	Result res = datenbank->getResult();
+	unlock();
+	befehl->release();
+	if( !res.zeilenAnzahl )
+	{
+		res.destroy();
+		return 0;
+	}
+	bool ret = res.values[ 0 ].istGleich( "t" );
+	res.destroy();
+	return ret;
+}
+
+bool CSDatenbank::chatroomBeitreten( int accountId, int chatroomId )
+{
+	Text *befehl = new Text( "INSERT INTO chatroom_spieler values( " );
+	befehl->append( chatroomId );
+	befehl->append( " , " );
+	befehl->append( accountId );
+	befehl->append( " )" );
+	lock();
+	bool ret = datenbank->befehl( befehl->getText() );
+	unlock();
+	befehl->release();
+	return ret;
+}
+
+int CSDatenbank::chatroomVerlassen( int accountId, int chatroomId )
+{
+	Text *befehl = new Text( "SELECT chatroom_verlassen( " );
+	befehl->append( chatroomId );
+	befehl->append( ", " );
+	befehl->append( accountId );
+	befehl->append( " )" );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	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 CSDatenbank::getChatroomAdmin( int chatroomId )
+{
+	Text *befehl = new Text( "SELECT admin_account_id FROM chatroom WHERE id = " );
+	befehl->append( chatroomId );
+	lock();
+	datenbank->befehl( befehl->getText() );
+	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;
+}
+
+// constant
+Text *CSDatenbank::getLetzterFehler() const
+{
+	return datenbank->getLetzterFehler();
+}
+
+// Reference Counting
+CSDatenbank *CSDatenbank::getThis()
+{
+	ref++;
+	return this;
+}
+
+CSDatenbank *CSDatenbank::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 74 - 0
ChatServer/Datenbank.h

@@ -0,0 +1,74 @@
+#ifndef Datenbank_H
+#define Datenbank_H
+
+#include <sql.h>
+#include <Text.h>
+#include <Array.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+using namespace sql;
+
+namespace Admin_Recht
+{
+	const int CSStarten = 0x00000018;
+	const int CSBeenden = 0x00000019;
+	const int CSPausieren = 0x0000001A;
+	const int CSMCChange = 0x0000001B;
+}
+
+class CSDatenbank
+{
+private:
+	Datenbank *datenbank;
+	CRITICAL_SECTION cs;
+	int ref;
+
+public:
+	// Konstruktor
+	CSDatenbank( InitDatei *zIni );
+	// Destruktor
+	~CSDatenbank();
+	// nicht constant
+	void lock();
+	void unlock();
+	int istAdministrator( const char *name, const char *passwort );
+	bool adminHatRecht( int id, int recht );
+	bool proveKlient( int num, int sNum );
+	Text *getKlientKey( int cId );
+	void unregisterKlient( int num, int sNum );
+	bool serverAnmelden( InitDatei *zIni );
+	bool setServerStatus( int id, int status );
+	bool setMaxClients( int id, int maxC );
+	int getAdminPort( int id );
+	bool serverIstNichtPausiert( int id );
+	int getKlientAccountId( int klientId );
+	int getAccountFreunde( int accountId, Array< int > *fAccountId );
+	int getAccountOnlineFreunde( int accountId, Array< int > *fAccountId );
+	bool accountNameChange( int accountId, const char *name );
+	bool beendeFreundschaft( int accountId1, int accountId2 );
+	bool proveFreundschaftsAnfrage( int vonAccountId, int zuAccountId );
+	bool saveFreundschaftsAnfrage( int vonAccountId, int zuAccountId );
+	int getFreundschaftsAnfragen( int accountId, Array< int > *vonAccountIds );
+	bool neueFreundschaft( int accountId1, int accountId2 );
+	Text *getAccountRufName( int accountId );
+	bool accountIstOnline( int accountId );
+	bool accountIstImSpiel( int accountId );
+	int getChatServerId( int accountId );
+	bool getChatServerIpPort( int serverId, unsigned short *port, char **ip );
+	int getChatNachrichten( int accountId, Array< int > *vonAccount, RCArray< Text > *nachricht );
+	bool speicherChatNachricht( int vonAccount, int zuAccount, const char *nachricht );
+	int getChatroomAccount( int chatroomId, Array< int > *accountId );
+	int chatroomErstellen( int accountId, const char *name );
+	bool proveChatroomEinladung( int vonAccount, int zuAccount, int chatroomId );
+	bool chatroomBeitreten( int accountId, int chatroomId );
+	int chatroomVerlassen( int accountId, int chatroomId );
+	int getChatroomAdmin( int chatroomId );
+	// constant
+	Text *getLetzterFehler() const;
+	// Reference Counting
+	CSDatenbank *getThis();
+	CSDatenbank *release();
+};
+
+#endif

+ 55 - 0
ChatServer/main.cpp

@@ -0,0 +1,55 @@
+#include "ChatServer.h"
+#ifdef WIN32
+#include <main.h>
+#endif
+#include <Zeit.h>
+#include <iostream>
+#include <fstream>
+#include <Globals.h>
+
+#ifdef WIN32
+int KSGStart Framework::Start( Startparam p )
+{
+#else
+int main()
+{
+    Framework::initFramework();
+#endif
+	Zeit *z = getZeit();
+	Text *pfad = new Text( "../log/chat/" );
+	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 << "CS: Startet...\n";
+	std::cout << "CS: Lese init Datei ../data/csInit.ini ...\n";
+	InitDatei *dat = new InitDatei( "../data/csInit.ini" );
+	if( !dat->laden() )
+	{
+		std::cout << "CS: error: Datei konnte nicht gelesen werden. Das Programm wird geschlossen.\n";
+		dat->release();
+		exit( 1 );
+	}
+
+	ChatServer *cServer = new ChatServer( dat );
+
+	std::cout << "CS: Der Admin Server läuft. Startforgang beendet.\n";
+	cServer->runn();
+
+	cServer->ende();
+	cServer->release();
+	dat->speichern();
+	dat->release();
+	std::cout << "CS: Der Server ist heruntergefahren.\n";
+	file.close();
+	std::cout.rdbuf( sbuf );
+#ifndef WIN32
+    Framework::releaseFramework();
+#endif
+	return 0;
+}

BIN
ChatServer/readme/images/ArchOptions.gif


BIN
ChatServer/readme/images/ChangeRemote.gif


BIN
ChatServer/readme/images/ManageConnections.gif


BIN
ChatServer/readme/images/OutputTypes.gif


BIN
ChatServer/readme/images/debuggerexport.png


BIN
ChatServer/readme/images/firstconnection.png


BIN
ChatServer/readme/images/linker.png


BIN
ChatServer/readme/images/postbuild.png


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

+ 11 - 0
data/csInit.ini

@@ -0,0 +1,11 @@
+DBBenutzer=chatserveru
+DBPasswort=LTChatServerPW
+DBName=koljadb
+DBIP=127.0.0.1
+DBPort=5432
+ServerName=Test
+ServerPort=49142
+ServerIP=198.168.2.173
+AdminServerPort=49141
+Aktiv=FALSE
+MaxClients=50