Explorar el Código

automatische speicherabbild erzeugung bei server crashes

Kolja Strohm hace 6 años
padre
commit
e8dc3e6028

+ 37 - 41
ChatServer/ChatServer.cpp

@@ -32,7 +32,6 @@ ChatServer::ChatServer( InitDatei *zIni )
 	db->setServerStatus( id, 2 );
 	end = 0;
 	nichtPausiert = 0;
-	InitializeCriticalSection( &cs );
 	ref = 1;
 	if( zIni->zWert( "Aktiv" )->istGleich( "TRUE" ) )
 	{
@@ -51,7 +50,6 @@ ChatServer::~ChatServer()
 	aServer->release();
 	ini->release();
 	db->release();
-	DeleteCriticalSection( &cs );
 	if( klients )
 		klients->release();
 }
@@ -87,10 +85,10 @@ void ChatServer::thread()
 			break;
 		Framework::getThreadRegister()->cleanUpClosedThreads();
 		CSKlient *clHandle = new CSKlient( klient, getThis() );
-		EnterCriticalSection( &cs );
+		cs.lock();
 		klients->set( clHandle, klientAnzahl );
 		klientAnzahl++;
-		LeaveCriticalSection( &cs );
+		cs.unlock();
 		clHandle->start();
 	}
 }
@@ -102,12 +100,12 @@ void ChatServer::close()
 #ifdef WIN32
 	warteAufThread( 1000 );
 #endif
-	EnterCriticalSection( &cs );
+	cs.lock();
 	for( int i = 0; i < klientAnzahl; i++ )
 		klients->z( i )->absturz();
 	klients = klients->release();
 	klientAnzahl = 0;
-	LeaveCriticalSection( &cs );
+	cs.unlock();
 	ende();
 	run = 0;
 	end = 1;
@@ -208,7 +206,7 @@ bool ChatServer::setMaxKlients( int mc )
 bool ChatServer::absturzKlient( int klientId )
 {
 	bool gefunden = 0;
-	EnterCriticalSection( &cs );
+	cs.lock();
 	for( int i = 0; i < klientAnzahl; i++ )
 	{
 		if( klients->z( i )->getKlientNummer() == klientId )
@@ -220,14 +218,14 @@ bool ChatServer::absturzKlient( int klientId )
 			i--;
 		}
 	}
-	LeaveCriticalSection( &cs );
+	cs.unlock();
 	return gefunden;
 }
 
 bool ChatServer::removeAccount( int accId )
 {
 	bool gefunden = 0;
-	EnterCriticalSection( &cs );
+	cs.lock();
 	for( int i = 0; i < klientAnzahl; i++ )
 	{
 		if( klients->z( i )->getAccountId() == accId )
@@ -238,14 +236,14 @@ bool ChatServer::removeAccount( int accId )
 			i--;
 		}
 	}
-	LeaveCriticalSection( &cs );
+	cs.unlock();
 	return gefunden;
 }
 
 bool ChatServer::removeKlient( int klientId )
 {
 	bool gefunden = 0;
-	EnterCriticalSection( &cs );
+	cs.lock();
 	for( int i = 0; i < klientAnzahl; i++ )
 	{
 		if( klients->z( i )->getKlientNummer() == klientId )
@@ -257,14 +255,14 @@ bool ChatServer::removeKlient( int klientId )
 			i--;
 		}
 	}
-	LeaveCriticalSection( &cs );
+	cs.unlock();
 	return gefunden;
 }
 
 bool ChatServer::removeKlient( CSKlient *zKlient )
 {
 	bool gefunden = 0;
-	EnterCriticalSection( &cs );
+	cs.lock();
 	for( int i = 0; i < klientAnzahl; i++ )
 	{
 		if( klients->z( i ) == zKlient )
@@ -276,7 +274,7 @@ bool ChatServer::removeKlient( CSKlient *zKlient )
 			break;
 		}
 	}
-	LeaveCriticalSection( &cs );
+	cs.unlock();
 	return gefunden;
 }
 
@@ -294,7 +292,7 @@ int ChatServer::getKlientStatus( int klientNummer, CSKlient *zKlient )
 {
 	bool empf = 0;
 	bool send = 0;
-	EnterCriticalSection( &cs );
+	cs.lock();
 	for( int i = 0; i < klientAnzahl; i++ )
 	{
 		if( klients->z( i )->getKlientNummer() == klientNummer &&  klients->z( i ) != zKlient )
@@ -305,7 +303,7 @@ int ChatServer::getKlientStatus( int klientNummer, CSKlient *zKlient )
 				send = 1;
 		}
 	}
-	LeaveCriticalSection( &cs );
+	cs.unlock();
 	if( !empf )
 		return 0;
 	if( !send )
@@ -316,7 +314,7 @@ int ChatServer::getKlientStatus( int klientNummer, CSKlient *zKlient )
 CSKlient *ChatServer::zSendeKlient( int accountId )
 {
 	CSKlient *ret = 0;
-	EnterCriticalSection( &cs );
+	cs.lock();
 	for( int i = 0; i < klientAnzahl; i++ )
 	{
 		if( klients->z( i )->getAccountId() == accountId && !klients->z( i )->istEmpfang() )
@@ -325,7 +323,7 @@ CSKlient *ChatServer::zSendeKlient( int accountId )
 			break;
 		}
 	}
-	LeaveCriticalSection( &cs );
+	cs.unlock();
 	return ret;
 }
 
@@ -676,14 +674,13 @@ 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 };
+	unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 	klient->setSendeKey( (char*)key, 20 );
 	klient->setEmpfangKey( (char*)key, 20 );
 	klientNummer = 0;
 	this->cs = cs;
 	accountId = 0;
 	empfangen = 1;
-	InitializeCriticalSection( &ts );
 	ref = 1;
 }
 
@@ -694,18 +691,17 @@ CSKlient::~CSKlient()
 	cs->addGesendet( klient->getUploadBytes( 1 ) );
 	klient->release();
 	cs->release();
-	DeleteCriticalSection( &ts );
 }
 
 // nicht constant 
 void CSKlient::lock()
 {
-	EnterCriticalSection( &ts );
+    ts.lock();
 }
 
 void CSKlient::unlock()
 {
-	LeaveCriticalSection( &ts );
+    ts.unlock();
 }
 
 void CSKlient::absturz()
@@ -2538,7 +2534,7 @@ bool MSGWeiterleitung::kickKlient( int accountId )
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );
@@ -2588,7 +2584,7 @@ bool MSGWeiterleitung::accountOnline( int accountId )
 			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 };
+				unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 				klient->setSendeKey( (char*)key, 20 );
 				klient->setEmpfangKey( (char*)key, 20 );
 				ret = ret & klient->verbinde( port, ip );
@@ -2641,7 +2637,7 @@ bool MSGWeiterleitung::accountOffline( int accountId )
 			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 };
+				unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 				klient->setSendeKey( (char*)key, 20 );
 				klient->setEmpfangKey( (char*)key, 20 );
 				ret = ret & klient->verbinde( port, ip );
@@ -2692,7 +2688,7 @@ bool MSGWeiterleitung::chatNachricht( int vonAccount, int zuAccount, const char
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );
@@ -2748,7 +2744,7 @@ bool MSGWeiterleitung::accountStatusChange( int accountId, const char *status )
 			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 };
+				unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 				klient->setSendeKey( (char*)key, 20 );
 				klient->setEmpfangKey( (char*)key, 20 );
 				ret = ret & klient->verbinde( port, ip );
@@ -2806,7 +2802,7 @@ bool MSGWeiterleitung::accountNameChange( int accountId, const char *name )
 			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 };
+				unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 				klient->setSendeKey( (char*)key, 20 );
 				klient->setEmpfangKey( (char*)key, 20 );
 				ret = ret & klient->verbinde( port, ip );
@@ -2856,7 +2852,7 @@ bool MSGWeiterleitung::accountKeinFreundMehr( int accountId, int zielAccountId )
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );
@@ -2902,7 +2898,7 @@ bool MSGWeiterleitung::freundesAnfrage( int vonAccountId, int zuAccountId )
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );
@@ -2948,7 +2944,7 @@ bool MSGWeiterleitung::neuerFreund( int accountId, int zuAccountId )
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );
@@ -2994,7 +2990,7 @@ bool MSGWeiterleitung::einladungZumChatroom( int vonAccountId, int zuAccountId,
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );
@@ -3048,7 +3044,7 @@ bool MSGWeiterleitung::spielerBetrittChatroom( int accountId, int chatroomId )
 			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 };
+				unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 				klient->setSendeKey( (char*)key, 20 );
 				klient->setEmpfangKey( (char*)key, 20 );
 				ret = ret & klient->verbinde( port, ip );
@@ -3105,7 +3101,7 @@ bool MSGWeiterleitung::chatroomNachricht( int vonAccount, const char *nachricht,
 			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 };
+				unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 				klient->setSendeKey( (char*)key, 20 );
 				klient->setEmpfangKey( (char*)key, 20 );
 				ret = ret & klient->verbinde( port, ip );
@@ -3161,7 +3157,7 @@ bool MSGWeiterleitung::spielerLeavestChatroom( int accountId, int chatroomId )
 			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 };
+				unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 				klient->setSendeKey( (char*)key, 20 );
 				klient->setEmpfangKey( (char*)key, 20 );
 				ret = ret & klient->verbinde( port, ip );
@@ -3210,7 +3206,7 @@ bool MSGWeiterleitung::freundEinladungAbgelehnt( int accountId, int zuAccountId
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );
@@ -3256,7 +3252,7 @@ bool MSGWeiterleitung::chatroomEinladungAbgelehnt( int accountId, int chatroomId
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );
@@ -3306,7 +3302,7 @@ bool MSGWeiterleitung::fehler( int zuAccountId, const char *fehler )
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );
@@ -3353,7 +3349,7 @@ bool MSGWeiterleitung::chatroomAdmin( int chatroomId, int zuAccountId )
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );
@@ -3399,7 +3395,7 @@ bool MSGWeiterleitung::chatroomKick( int chatroomId, int accountId )
 		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 };
+			unsigned char key[ 20 ] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 };
 			klient->setSendeKey( (char*)key, 20 );
 			klient->setEmpfangKey( (char*)key, 20 );
 			ret = ret & klient->verbinde( port, ip );

+ 2 - 2
ChatServer/ChatServer.h

@@ -22,7 +22,7 @@ private:
 	Server *aServer;
 	InitDatei *ini;
 	CSDatenbank *db;
-	CRITICAL_SECTION cs;
+	Critical cs;
 	RCArray< CSKlient > *klients;
 	Text *fehler;
 	int klientAnzahl;
@@ -93,7 +93,7 @@ private:
 	unsigned int klientNummer;
 	unsigned int accountId;
 	ChatServer *cs;
-	CRITICAL_SECTION ts;
+	Critical ts;
 	bool empfangen;
 	int ref;
 

+ 1 - 0
ChatServer/ChatServer.vcxproj

@@ -93,6 +93,7 @@
     </Link>
     <ClCompile>
       <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+      <PreprocessorDefinitions>DEBUG</PreprocessorDefinitions>
     </ClCompile>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

+ 5 - 7
ChatServer/Datenbank.cpp

@@ -13,7 +13,6 @@ CSDatenbank::CSDatenbank( InitDatei *zIni )
         std::cout << "CS: Die Verbindung zur Datenbank konnte nicht hergestellt werden.\nDas Programm wird beendet.";
         exit( 1 );
     }
-	InitializeCriticalSection( &cs );
 	ref = 1;
     Text befehl = "SELECT port, admin_port  FROM server WHERE id = ";
     befehl += zIni->zWert( "ServerId" )->getText();
@@ -33,18 +32,17 @@ CSDatenbank::CSDatenbank( InitDatei *zIni )
 CSDatenbank::~CSDatenbank()
 {
 	datenbank->release();
-	DeleteCriticalSection( &cs );
 }
 
 // nicht constant
 void CSDatenbank::lock()
 {
-	EnterCriticalSection( &cs );
+    cs.lock();
 }
 
 void CSDatenbank::unlock()
 {
-	LeaveCriticalSection( &cs );
+    cs.unlock();
 }
 
 int CSDatenbank::istAdministrator( const char *name, const char *passwort )
@@ -246,10 +244,10 @@ int CSDatenbank::getAccountOnlineFreunde( int accountId, Array< int > *fAccountI
 {
 	Text *befehl = new Text( "SELECT freund.account_id AS freundId FROM freund, account_client WHERE freund.freund_account_id = " );
 	befehl->append( accountId );
-	befehl->append( " AND freund.account_id = account_clients.account_id "
+	befehl->append( " AND freund.account_id = account_client.account_id "
 					  "UNION SELECT freund.freund_account_id AS freundId FROM freund, account_client WHERE freund.account_id = " );
 	befehl->append( accountId );
-	befehl->append( " AND freund.freund_account_id = account_clients.account_id " );
+	befehl->append( " AND freund.freund_account_id = account_client.account_id " );
 	lock();
 	datenbank->befehl( befehl->getText() );
 	Result res = datenbank->getResult();
@@ -455,7 +453,7 @@ bool CSDatenbank::accountIstImSpiel( int accountId )
 int CSDatenbank::getChatServerId( int accountId )
 {
 	Text *befehl = new Text( "SELECT a.server_id FROM server_client a, account_client b, server c "
-							 "WHERE a.client_id = b.client_id AND and a.server_id = c.id AND c.server_typ_name = 'chat' AND b.account_id = " );
+							 "WHERE a.client_id = b.client_id AND a.server_id = c.id AND c.server_typ_name = 'chat' AND b.account_id = " );
 	befehl->append( accountId );
 	lock();
 	datenbank->befehl( befehl->getText() );

+ 2 - 1
ChatServer/Datenbank.h

@@ -5,6 +5,7 @@
 #include <Text.h>
 #include <Array.h>
 #include <InitDatei.h>
+#include <Critical.h>
 
 using namespace Framework;
 using namespace sql;
@@ -21,7 +22,7 @@ class CSDatenbank
 {
 private:
 	Datenbank *datenbank;
-	CRITICAL_SECTION cs;
+	Critical cs;
 	int ref;
 
 public:

+ 5 - 2
ChatServer/main.cpp

@@ -3,11 +3,15 @@
 #include <iostream>
 #include <fstream>
 #include <Globals.h>
+#include <sys/resource.h>
 
 int main()
 {
+	struct rlimit core_limits;
+	core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
+	setrlimit(RLIMIT_CORE, &core_limits);
 #ifdef DEBUG
-    cd( "/test/anmeldung" );
+    //chdir( "/ksg/Server/chat" );
 #endif
     Framework::initFramework();
 	Zeit *z = getZeit();
@@ -48,7 +52,6 @@ int main()
 
 	cServer->ende();
 	cServer->release();
-	dat->speichern();
 	dat->release();
 	std::cout << "CS: Der Server ist heruntergefahren.\n";
 	file.close();