#include "Server.h" #include #include #include #include #include // Inhalt der LoginServer Klasse aus LoginServer.h // Konstruktor FactoryCraftServer::FactoryCraftServer( InitDatei* zIni ) : ReferenceCounter() { Network::Start( 100 ); klients = new RCArray< FCKlient >(); empfangen = 0; gesendet = 0; ini = dynamic_cast(zIni->getThis()); id = *zIni->zWert( "ServerId" ); server = new SSLServer(); server->setPrivateKeyPassword( zIni->zWert( "SSLPasswort" )->getText() ); server->setCertificateFile( zIni->zWert( "SSLCert" )->getText() ); std::cout << "using cert file " << zIni->zWert( "SSLCert" )->getText() << "\n"; server->setPrivateKeyFile( zIni->zWert( "SSLKey" )->getText() ); std::cout << "using private key " << zIni->zWert( "SSLKey" )->getText() << "\n"; game = new Game( zIni->zWert( "World" )->getText(), zIni->zWert( "SaveDir" )->getText() ); InitializeCriticalSection( &cs ); } // Destruktor FactoryCraftServer::~FactoryCraftServer() { server->trenne(); server->release(); if( klients ) klients->release(); ini->release(); game->requestStop(); game->release(); DeleteCriticalSection( &cs ); } // nicht constant void FactoryCraftServer::run() { if( !server->verbinde( (unsigned short)TextZuInt( ini->zWert( "SSLPort" )->getText(), 10 ), 10 ) ) std::cout << "Der Server konnte nicht gestartet werden.\n"; else std::cout << "Server Port: " << ini->zWert( "SSLPort" )->getText() << "\n"; while( server->isConnected() ) { SSLSKlient* klient = server->getKlient(); if( !klient ) continue; Framework::getThreadRegister()->cleanUpClosedThreads(); FCKlient* clHandle = new FCKlient( klient, dynamic_cast(getThis()) ); EnterCriticalSection( &cs ); klients->add( clHandle ); LeaveCriticalSection( &cs ); clHandle->start(); } } void FactoryCraftServer::close() { server->trenne(); EnterCriticalSection( &cs ); for( int i = 0; i < klients->getEintragAnzahl(); i++ ) klients->z( i )->absturz(); klients = (RCArray< FCKlient > *)klients->release(); game->save(); LeaveCriticalSection( &cs ); } bool FactoryCraftServer::absturzKlient( int accountId ) { bool gefunden = 0; EnterCriticalSection( &cs ); for( int i = 0; i < klients->getEintragAnzahl(); i++ ) { if( klients->z( i ) && klients->z( i )->getAccountId() == accountId ) { klients->z( i )->absturz(); klients->remove( i ); gefunden = 1; break; } } LeaveCriticalSection( &cs ); return gefunden; } bool FactoryCraftServer::removeKlient( FCKlient* zKlient ) { bool gefunden = 0; EnterCriticalSection( &cs ); for( int i = 0; i < klients->getEintragAnzahl(); i++ ) { if( klients->z( i ) == zKlient ) { klients->remove( i ); gefunden = 1; break; } } LeaveCriticalSection( &cs ); return gefunden; } void FactoryCraftServer::addGesendet( int bytes ) { gesendet += bytes; } void FactoryCraftServer::addEmpfangen( int bytes ) { empfangen += bytes; } bool FactoryCraftServer::hatClients() const { return klients->hat( 0 ); } Game* FactoryCraftServer::zGame() const { return game; } // Inhalt der LSKlient aus LoginServer.h // Konstruktor FCKlient::FCKlient( SSLSKlient* klient, FactoryCraftServer* ls ) : Thread() { this->klient = klient; accountId = 0; this->ls = ls; reader = new NetworkReader( klient ); writer = new NetworkWriter( klient ); } // Destruktor FCKlient::~FCKlient() { if( zGameClient ) { zGameClient->logout(); zGameClient = (GameClient*)zGameClient->release(); } delete reader; delete writer; klient->release(); ls->release(); } // nicht constant void FCKlient::absturz() { ende(); klient->trenne(); } void FCKlient::thread() { while( 1 ) { char c = 0; if( !klient->getNachricht( &c, 1 ) ) break; else { bool br = 0; switch( c ) { case 1: // Klient identifikation { int accountId = 0; klient->getNachricht( (char*)&accountId, 4 ); unsigned char secretLength = 0; klient->getNachricht( (char*)&secretLength, 1 ); char* secret = new char[ secretLength + 1 ]; klient->getNachricht( secret, (int)secretLength ); secret[ secretLength ] = 0; Text data = "{\"account_id\":"; data += accountId; data += ", \"secret\": \""; data += secret; data += "\"}"; bool ok = false; HTTP::Answer* answer = HTTP::PostRequest( "/game_client/api/verify_client.php", "koljastrohm-games.com", data, "application/json", 443, true ).execute(); if( answer->getStatusCode() == 200 ) { JSON::JSONObject obj( answer->getData() ); if( obj.hasValue( "verified" ) ) { JSON::JSONValue* value = obj.getValue( "verified" ); if( value->getType() == JSON::JSONType::BOOLEAN ) { if( ((JSON::JSONBool*)value)->getBool() ) { this->accountId = accountId; if( zGameClient ) { zGameClient->logout(); zGameClient = (GameClient*)zGameClient->release(); } klient->sende( "\1", 1 ); zGameClient = ls->zGame()->addPlayer( dynamic_cast(getThis()), Text( accountId ) ); ok = true; } } value->release(); } } answer->release(); delete[]secret; if( !ok ) klient->sende( "\0", 1 ); break; } case 2: // Verbindungsende br = 1; if( zGameClient ) { zGameClient->logout(); zGameClient = (GameClient*)zGameClient->release(); } klient->sende( "\1", 1 ); break; default: if( zGameClient ) zGameClient->addMessage( reader ); break; } if( br ) break; ls->addEmpfangen( klient->getDownloadBytes( 1 ) ); ls->addGesendet( klient->getUploadBytes( 1 ) ); } } ls->addEmpfangen( klient->getDownloadBytes( 1 ) ); ls->addGesendet( klient->getUploadBytes( 1 ) ); ls->removeKlient( this ); // delete this } int FCKlient::getAccountId() const // gibt die KlientId zurück { return accountId; } SSLSKlient* FCKlient::zClient() const { return klient; } NetworkWriter* FCKlient::zWriter() const { return writer; }