#ifdef WIN32 #include "..\SpielServer.h" #include "..\..\Datenbank\Datenbank.h" #else #include "SpielServer.h" #include "Datenbank.h" #include #define Sleep( x ) usleep( (x) * 1000 ) #endif #include // Inhalt der SpielErstellt Kasse aus SpielErstellt.h // Konstruktor SpielErstellt::SpielErstellt( int id, SpielServer *ss ) : Thread() { this->ss = ss; this->id = id; karte = ss->zDB()->getKarteVonErstelltemSpiel( id ); spielArt = ss->zDB()->getSpielArtId( karte ); accounts = new Array< int >(); spielerAnzahl = ss->zDB()->getSpielErstelltSpieler( id, accounts ); klients = new RCArray< SSKlient >(); status = new Array< int >(); verbunden = 0; state = 0; abbr = 0; spielId = 0; ref = 1; } // Destruktor SpielErstellt::~SpielErstellt() { ss->release(); accounts->release(); klients->release(); status->release(); } // nicht constant void SpielErstellt::abbruch() { abbr = 1; } void SpielErstellt::sendeVerbindungsBefehl() { unsigned short sPort = (unsigned short)ss->getPort(); char *sIp = ss->getIp(); unsigned char *sIp4 = new unsigned char[ 4 ]; Text *tmpT = new Text( sIp ); Text *ip1 = tmpT->getTeilText( 0, tmpT->positionVon( '.' ) ); Text *ip2 = tmpT->getTeilText( tmpT->positionVon( '.' ) + 1, tmpT->positionVon( '.', 1 ) ); Text *ip3 = tmpT->getTeilText( tmpT->positionVon( '.', 1 ) + 1, tmpT->positionVon( '.', 2 ) ); Text *ip4 = tmpT->getTeilText( tmpT->positionVon( '.', 2 ) + 1 ); sIp4[ 0 ] = (unsigned char)TextZuInt( ip1->getText(), 10 ); sIp4[ 1 ] = (unsigned char)TextZuInt( ip2->getText(), 10 ); sIp4[ 2 ] = (unsigned char)TextZuInt( ip3->getText(), 10 ); sIp4[ 3 ] = (unsigned char)TextZuInt( ip4->getText(), 10 ); ip1->release(); ip2->release(); ip3->release(); ip4->release(); tmpT->release(); for( int i = 0; i < spielerAnzahl; i++ ) { int accId = accounts->hat( i ) ? accounts->get( i ) : 0; int port = 0; Text *ip = new Text( "" ); if( ss->zDB()->getChatServerPortIp( accId, &port, ip ) ) { char ret = 0; Klient *klient = new Klient(); 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 ); klient->verbinde( (unsigned short)port, ip->getText() ); klient->sendeEncrypted( "\5\x1D", 2 ); klient->getNachrichtEncrypted( &ret, 1 ); if( ret != 3 ) { klient->sendeEncrypted( (char*)&accId, 4 ); klient->sendeEncrypted( (char*)&sPort, 2 ); klient->sendeEncrypted( (char*)sIp4, 4 ); klient->getNachrichtEncrypted( &ret, 1 ); } if( ret == 3 ) { char len = 0; klient->getNachrichtEncrypted( &len, 1 ); char *err = new char[ len ]; klient->getNachrichtEncrypted( err, len ); delete[] err; } klient->sendeEncrypted( "\3", 1 ); klient->getNachrichtEncrypted( &ret, 1 ); ss->addEmpfangen( klient->getDownloadBytes( 1 ) ); ss->addGesendet( klient->getUploadBytes( 1 ) ); klient->trenne(); klient->release(); } ip->release(); } delete[] sIp4; start(); } bool SpielErstellt::klientVerbunden( SSKlient *klient ) { if( verbunden == spielerAnzahl ) { klient->release(); return 0; } int accId = klient->getAccountId(); bool ret = 0; for( int i = 0; i < spielerAnzahl; i++ ) { if( accounts->hat( i ) && accounts->get( i ) == accId ) { if( state == 1 ) klient->spielGefunden( karte ); klients->set( klient, i ); status->set( 1, i ); verbunden++; klient->setSpielErstellt( this ); ret = 1; break; } } if( !ret ) klient->release(); return ret; } bool SpielErstellt::klientNimmtAn( int accountId ) { if( !verbunden || state != 1 ) return 0; bool ret = 0; for( int i = 0; i < spielerAnzahl; i++ ) { if( accounts->hat( i ) && accounts->get( i ) == accountId ) { status->set( 2, i ); ret = 1; break; } } return ret; } bool SpielErstellt::klientLehntAb( int accountId ) { if( !verbunden || state != 1 ) return 0; bool ret = 0; for( int i = 0; i < spielerAnzahl; i++ ) { if( accounts->hat( i ) && accounts->get( i ) == accountId ) { status->set( 3, i ); ret = 1; break; } } return ret; } bool SpielErstellt::klientGetrennt( SSKlient *zKlient ) { if( !verbunden ) return 0; int accId = zKlient->getAccountId(); bool ret = 0; for( int i = 0; i < spielerAnzahl; i++ ) { if( accounts->hat( i ) && accounts->get( i ) == accId ) { if( status->hat( i ) && status->get( i ) != 0 ) { zKlient->setSpielErstellt( 0 ); status->set( 0, i ); verbunden--; klients->set( 0, i ); ret = 1; } break; } } return ret; } void SpielErstellt::thread() { state = 1; double time = 0; ZeitMesser *zeit = new ZeitMesser(); int nachrichtSenden = 1; while( time < 10 ) { // warten auf annahme von allen Spielern if( abbr ) break; zeit->messungStart(); Sleep( 100 ); bool br = 0; bool st2 = 1; for( int i = 0; i < spielerAnzahl; i++ ) { if( status->hat( i ) && status->get( i ) == 3 ) { br = 1; for( int j = 0; j < spielerAnzahl; j++ ) { if( j != i ) status->set( 2, j ); } break; } if( st2 ) st2 = status->hat( i ) && status->get( i ) == 2; } if( st2 ) br = 1; if( br ) { zeit->messungEnde(); break; } char verbleibend = (char)( 10 - (char)time ); if( verbleibend < 0 ) verbleibend = 0; if( time > nachrichtSenden ) { for( int i = 0; i < spielerAnzahl; i++ ) { if( status->hat( i ) && status->get( i ) != 0 ) { SSKlient *tmp = klients->z( i ); if( tmp ) tmp->zeitVerbleibend( verbleibend ); } } nachrichtSenden++; } zeit->messungEnde(); time += zeit->getSekunden(); } // prüfen ob alle Spieler bereit sind state = 2; bool abbruch = verbunden != spielerAnzahl; const char *err = "Ein Spieler konnte nicht erreicht werden."; if( !abbruch ) { for( int i = 0; i < spielerAnzahl; i++ ) { if( !status->hat( i ) || status->get( i ) != 2 ) { abbruch = 1; err = "Ein Spieler ist noch nicht bereit."; break; } } } if( abbr ) { err = "Das Spiel wurde Wegen abwesenheit eines Spielers Abgebrochen."; abbruch = 1; for( int j = 0; j < spielerAnzahl; j++ ) status->set( 2, j ); } if( abbruch ) { // Es sind nicht alle bereit Vorgang abbrechen for( int i = 0; i < spielerAnzahl; i++ ) { if( status->hat( i ) && status->get( i ) != 0 ) { SSKlient *tmp = klients->z( i ); if( tmp ) tmp->erstellungAbgebrochen( (char*)err ); } } Array< bool > *inWarteschlange = new Array< bool >(); RCArray< Zeit > *wZeit = new RCArray< Zeit >(); if( ss->zDB()->spielErstelltAbbruch( id, spielerAnzahl, accounts, status, inWarteschlange, wZeit ) ) // zurück in Warteschlange { for( int i = 0; i < spielerAnzahl; i++ ) { if( inWarteschlange->hat( i ) && inWarteschlange->get( i ) ) { SSKlient *tmp = klients->z( i ); if( tmp ) { Zeit *zTmp = wZeit->z( i ); if( zTmp ) tmp->backInWarteschlange( (char)zTmp->zUhrzeit()->getStunde(), (char)zTmp->zUhrzeit()->getMinute(), (char)zTmp->zUhrzeit()->getSekunde() ); } } } } inWarteschlange->release(); wZeit->release(); for( int i = 0; i < spielerAnzahl; i++ ) { SSKlient *tmp = klients->z( i ); if( tmp ) tmp->trenne(); } zeit->release(); ss->removeSpielErstellt( id ); // delete this return; } // alle Spieler sind bereit Vorgang fortsetzen spielId = ss->zDB()->spielErstelltFortsetzen( id ); Spiel *weiter = new Spiel( spielId, ss->getThis() ); ss->addSpiel( weiter ); weiter->setAccounts( spielerAnzahl, accounts ); weiter->setKlients( spielerAnzahl, klients ); weiter->setKarteId( karte ); ss->removeSpielErstellt( id ); // delete this zeit->release(); } // constant int SpielErstellt::getId() const { return id; } // Reference Counting SpielErstellt *SpielErstellt::getThis() { ref++; return this; } SpielErstellt *SpielErstellt::release() { ref--; if( !ref ) delete this; return 0; } // Inhalt der SpielFinden Klasse aus SpielErstellt.h // Konstruktor SpielFinden::SpielFinden( SpielServer *ss ) : Thread() { this->ss = ss; end = 0; spielServerId = 0; ref = 1; } // Destruktor SpielFinden::~SpielFinden() { end = 1; warteAufThread( 2000 ); } // nicht constant void SpielFinden::setEnde() { end = 1; } void SpielFinden::setSpielServerId( int id ) { spielServerId = id; } void SpielFinden::thread() { end = 0; while( !end ) { for( int i = 0; i < 10 && !end; i++ ) Sleep( 1000 ); if( end ) break; int ret = ss->zDB()->erstelleSpiel( spielServerId ); if( !ret ) { // erfolg int id = ss->zDB()->getSpielErstelltId( spielServerId ); SpielErstellt *erstellt = new SpielErstellt( id, ss->getThis() ); ss->addSpielErstellt( erstellt ); erstellt->sendeVerbindungsBefehl(); ss->zDB()->deleteSpielErstelltNext( spielServerId ); } } run = 0; end = 0; } // constant // Reference Counting SpielFinden *SpielFinden::getThis() { ref++; return this; } SpielFinden *SpielFinden::release() { ref--; if( !ref ) delete this; return 0; }