123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- #include "Server.h"
- #include <iostream>
- #include <Klient.h>
- #include <Globals.h>
- #include <HttpRequest.h>
- #include <JSON.h>
- #include <AsynchronCall.h>
- // Inhalt der LoginServer Klasse aus LoginServer.h
- // Konstruktor
- FactoryCraftServer::FactoryCraftServer( InitDatei* zIni )
- : ReferenceCounter()
- {
- Network::Start( 100 );
- runningThreads = 0;
- klients = new RCArray< FCKlient >();
- ini = dynamic_cast<InitDatei*>(zIni->getThis());
- id = *zIni->zWert( "ServerId" );
- sslServer = new SSLServer();
- sslServer->setPrivateKeyPassword( zIni->zWert( "SSLPasswort" )->getText() );
- sslServer->setCertificateFile( zIni->zWert( "SSLCert" )->getText() );
- std::cout << "using cert file " << zIni->zWert( "SSLCert" )->getText() << "\n";
- sslServer->setPrivateKeyFile( zIni->zWert( "SSLKey" )->getText() );
- std::cout << "using private key " << zIni->zWert( "SSLKey" )->getText() << "\n";
- server = new Server();
- std::cout << "Server Port: " << ini->zWert( "Port" )->getText() << "\n";
- if( !server->verbinde( (unsigned short)TextZuInt( ini->zWert( "Port" )->getText(), 10 ), 10 ) )
- {
- std::cout << "Der Server konnte nicht gestartet werden.\n";
- exit( 1 );
- }
- std::cout << "SSL Server Port: " << ini->zWert( "SSLPort" )->getText() << "\n";
- if( !sslServer->verbinde( (unsigned short)TextZuInt( ini->zWert( "SSLPort" )->getText(), 10 ), 10 ) )
- {
- std::cout << "Der SSL Server konnte nicht gestartet werden.\n";
- exit( 2 );
- }
- Game::initialize( zIni->zWert( "World" )->getText(), zIni->zWert( "SaveDir" )->getText() );
- new Framework::AsynchronCall( "Server", [this]() {
- runningThreads++;
- while( server->isConnected() )
- {
- SKlient* klient = server->getKlient();
- if( !klient )
- continue;
- unsigned short len;
- klient->setEmpfangTimeout( 5000 );
- klient->getNachricht( (char*)&len, 2 );
- char* key = new char[ len ];
- klient->getNachricht( (char*)key, len );
- bool bg;
- klient->getNachricht( (char*)&bg, 1 );
- klient->setEmpfangTimeout( 0 );
- bool found = 0;
- EnterCriticalSection( &cs );
- for( FCKlient* client : *klients )
- {
- if( client->matchAuthKey( key, len ) )
- {
- if( bg )
- client->setBackgroundClient( klient );
- else
- client->setForegroundClient( klient );
- found = 1;
- break;
- }
- }
- LeaveCriticalSection( &cs );
- if( !found )
- klient->release();
- }
- runningThreads--;
- } );
- InitializeCriticalSection( &cs );
- }
- // Destruktor
- FactoryCraftServer::~FactoryCraftServer()
- {
- sslServer->trenne();
- server->trenne();
- while( runningThreads > 0 )
- Sleep( 100 );
- sslServer->release();
- server->release();
- if( klients )
- klients->release();
- ini->release();
- Game::INSTANCE->requestStop();
- Game::INSTANCE->release();
- DeleteCriticalSection( &cs );
- }
- // nicht constant
- void FactoryCraftServer::run()
- {
- runningThreads++;
- while( sslServer->isConnected() )
- {
- SSLSKlient* klient = sslServer->getKlient();
- if( !klient )
- continue;
- Framework::getThreadRegister()->cleanUpClosedThreads();
- FCKlient* clHandle = new FCKlient( klient, dynamic_cast<FactoryCraftServer*>(getThis()) );
- EnterCriticalSection( &cs );
- klients->add( clHandle );
- LeaveCriticalSection( &cs );
- clHandle->start();
- }
- runningThreads--;
- }
- void FactoryCraftServer::close()
- {
- sslServer->trenne();
- EnterCriticalSection( &cs );
- for( int i = 0; i < klients->getEintragAnzahl(); i++ )
- klients->z( i )->absturz();
- klients = (RCArray< FCKlient > *)klients->release();
- Game::INSTANCE->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;
- }
- bool FactoryCraftServer::hatClients() const
- {
- return klients->hat( 0 );
- }
- int FactoryCraftServer::getUnencryptedPort() const
- {
- return server->getPort();
- }
- char* randomKey( int& len )
- {
- len = 1024 + (int)(((double)rand() / RAND_MAX - 0.5) * 512);
- char* key = new char[ len ];
- for( int i = 0; i < len; i++ )
- key[ i ] = (char)(((double)rand() / RAND_MAX) * 256);
- return key;
- }
- // Inhalt der LSKlient aus LoginServer.h
- // Konstruktor
- FCKlient::FCKlient( SSLSKlient* klient, FactoryCraftServer* ls )
- : Thread()
- {
- this->klient = klient;
- background = 0;
- foreground = 0;
- accountId = 0;
- this->ls = ls;
- zGameClient = 0;
- backgroundReader = 0;
- foregroundReader = 0;
- backgroundWriter = 0;
- foregroundWriter = 0;
- authKey = randomKey( authKeyLen );
- }
- // Destruktor
- FCKlient::~FCKlient()
- {
- if( zGameClient )
- {
- zGameClient->logout();
- zGameClient = (GameClient*)zGameClient->release();
- }
- if( background )
- background->release();
- if( foreground )
- foreground->release();
- delete backgroundReader;
- delete foregroundReader;
- delete backgroundWriter;
- delete foregroundWriter;
- klient->release();
- ls->release();
- delete[] authKey;
- }
- // nicht constant
- void FCKlient::setForegroundClient( SKlient* foreground )
- {
- this->foreground = foreground;
- foregroundReader = new NetworkReader( foreground );
- foregroundWriter = new NetworkWriter( foreground );
- if( foreground && background )
- zGameClient = Game::INSTANCE->addPlayer( dynamic_cast<FCKlient*>(getThis()), Framework::Text( (int)accountId ) );
- new AsynchronCall( [this]() {
- while( this->foreground->waitForNextMessage() )
- {
- if( zGameClient )
- zGameClient->addMessage( foregroundReader );
- if( !zGameClient )
- Sleep( 100 );
- }
- zGameClient->logout();
- ls->removeKlient( this );
- } );
- }
- void FCKlient::setBackgroundClient( SKlient* background )
- {
- this->background = background;
- backgroundReader = new NetworkReader( background );
- backgroundWriter = new NetworkWriter( background );
- if( foreground && background )
- zGameClient = Game::INSTANCE->addPlayer( dynamic_cast<FCKlient*>(getThis()), Framework::Text( (int)accountId ) );
- new AsynchronCall( [this]() {
- while( this->background->waitForNextMessage() )
- {
- if( zGameClient )
- zGameClient->addMessage( backgroundReader );
- if( !zGameClient )
- Sleep( 100 );
- }
- zGameClient->logout();
- ls->removeKlient( this );
- } );
- }
- 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 );
- klient->sende( (char*)&authKeyLen, 4 );
- klient->sende( authKey, authKeyLen );
- int port = ls->getUnencryptedPort();
- klient->sende( (char*)&port, 4 );
- 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:
- br = 1;
- break;
- }
- if( br )
- break;
- }
- }
- }
- int FCKlient::getAccountId() const // gibt die KlientId zurück
- {
- return accountId;
- }
- NetworkWriter* FCKlient::zBackgroundWriter() const
- {
- return backgroundWriter;
- }
- NetworkWriter* FCKlient::zForegroundWriter() const
- {
- return foregroundWriter;
- }
- bool FCKlient::matchAuthKey( char* key, int len ) const
- {
- if( foreground && background )
- return 0;
- if( len != authKeyLen )
- return 0;
- for( int i = 0; i < len; i++ )
- {
- if( key[ i ] != authKey[ i ] )
- return 0;
- }
- return 1;
- }
|