#include "Statistik.h" #include #include #ifndef WIN32 #include #define Sleep( x ) usleep( (x) * 1000 ) #endif // Inhalt der Statistik Klasse aus Statistik.h // Konstruktor Statistik::Statistik() { spielId = 0; karteId = 0; db = 0; spielerAnzahl = 0; spieler = new RCArray< Spieler >(); erstellt = 0; sOnline = new Array< bool >(); sBereit = new Array< bool >(); gss = new RCArray< GesamtSpielerStatistik >(); gts = new RCArray< GesamtTeamStatistik >(); rrs = new RCArray< RundenRundenStatistik >(); teamNamen = 0; gewinnerTeam = new Array< int >(); rundenDauer = new Array< int >(); rundenBild = new RCArray< Bild >(); ref = 1; } // Destruktor Statistik::~Statistik() { if( db ) db->release(); spieler->release(); sOnline->release(); sBereit->release(); gss->release(); gts->release(); rrs->release(); if( teamNamen ) teamNamen->release(); gewinnerTeam->release(); rundenDauer->release(); rundenBild->release(); } // privat void Statistik::sendeStatistik( int index ) { // Sendet Statistik an Spieler index if( !sOnline->hat( index ) || !sOnline->get( index ) ) return; Klient *zk = spieler->z( index )->zKlient(); if( !zk ) return; int anz = gss->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) zk->sendeGesamtSpielerStatistik( gss->z( i ) ); anz = gts->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) zk->sendeGesamtTeamStatistik( gts->z( i ) ); anz = rrs->getEintragAnzahl(); for( int i = 0; i < anz; i++ ) zk->sendeRundeStatistik( rrs->z( i ) ); zk->sendeStatistikLadenFertig(); for( int i = 0; i < spielerAnzahl; i++ ) { if( !sOnline->hat( i ) || !sOnline->get( i ) ) zk->sendeStatistikSpielerOffline( spieler->z( i )->getAccountId() ); } } // nicht constant void Statistik::setSpielId( int id ) { spielId = id; } void Statistik::setKarteId( int id ) { karteId = id; } void Statistik::setPSQLDB( SSDatenbankV *db ) { if( this->db ) this->db->release(); this->db = db; } void Statistik::setTeamNamen( RCArray< Text > *namen ) { if( teamNamen ) teamNamen->release(); teamNamen = namen; } void Statistik::rundenEnde( int team, int dauer, Bild *b ) { gewinnerTeam->add( team ); rundenDauer->add( dauer ); Bild *rb = new Bild(); rb->neuBild( b->getBreite(), b->getHeight(), 0 ); rb->drawBild( 0, 0, rb->getBreite(), rb->getHeight(), *b ); rundenBild->add( rb ); b->release(); } void Statistik::setSpieler( int anzahl, RCArray< Spieler > *zSpieler ) { spielerAnzahl = anzahl; for( int i = 0; i < anzahl; i++ ) { spieler->set( zSpieler->get( i ), i ); sOnline->set( 0, i ); sBereit->set( 0, i ); } } void Statistik::klientOffline( int accountId ) { for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i )->getAccountId() == accountId ) { sOnline->set( 0, i ); sBereit->set( 0, i ); } else if( sOnline->hat( i ) && sOnline->get( i ) && spieler->z( i )->zKlient() ) spieler->z( i )->zKlient()->sendeStatistikSpielerOffline( accountId ); } } void Statistik::statistikAnfrage( int accountId, short len, char *bytes ) { len--; switch( *bytes ) { case 1: // Spieler ist Bereit for( int i = 0; i < spielerAnzahl; i++ ) { if( !erstellt ) { if( spieler->z( i )->getAccountId() == accountId ) sBereit->set( 1, i ); } else if( spieler->z( i )->getAccountId() == accountId ) { sendeStatistik( i ); break; } } break; case 2: // Chat Nachricht bytes++; char *txt = new char[ len + 1 ]; txt[ len ] = 0; for( int i = 0; i < len; i++ ) txt[ i ] = bytes[ i ]; for( int i = 0; i < spielerAnzahl; i++ ) { if( sOnline->hat( i ) && sOnline->get( i ) && spieler->z( i )->zKlient() ) spieler->z( i )->zKlient()->sendeStatistikChatNachricht( accountId, txt ); } delete[] txt; break; } } void Statistik::run() { for( int i = 0; i < spielerAnzahl; i++ ) sOnline->set( spieler->z( i )->istOnline(), i ); // Statistik erstellen // gesammt Spieler for( int i = 0; i < spielerAnzahl; i++ ) { if( spieler->z( i ) ) { Spieler *tmp = spieler->z( i ); InitDatei *d = new InitDatei(); Text w; w = tmp->getSpielerNummer(); if( w.getLength() ) d->addWert( "SpielerNummer", w.getText() ); Text *sn = db->getAccountRufName( tmp->getAccountId() ); if( sn && sn->getLength() ) d->addWert( "SpielerName", sn->getText() ); if( sn ) sn->release(); if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) ) d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() ); w = tmp->getSpielerFarbe(); if( w.getLength() ) d->addWert( "SpielerFarbe", w.getText() ); w = tmp->getTeamFarbe(); if( w.getLength() ) d->addWert( "TeamFarbe", w.getText() ); w = tmp->getRundenGewonnen(); if( w.getLength() ) d->addWert( "GewonneneRunden", w.getText() ); w = tmp->getPunkte(); if( w.getLength() ) d->addWert( "Punkte", w.getText() ); w = tmp->getLinienLength(); if( w.getLength() ) d->addWert( "LinienLänge", w.getText() ); w = tmp->getZeitAmLeben(); if( w.getLength() ) d->addWert( "ZeitAmLeben", w.getText() ); w = tmp->getZeitTod(); if( w.getLength() ) d->addWert( "ZeitTod", w.getText() ); w = tmp->getKills(); if( w.getLength() ) d->addWert( "Kills", w.getText() ); w = tmp->getTode(); if( w.getLength() ) d->addWert( "Tode", w.getText() ); GesamtSpielerStatistik *gss = new GesamtSpielerStatistik(); gss->initValues( d ); this->gss->add( gss ); } } // Gesamt Team for( int i = 0; i < spielerAnzahl; i++ ) { Spieler *tmp = spieler->z( i ); if( tmp ) { int anz = gts->getEintragAnzahl(); bool gefunden = 0; for( int j = 0; j < anz; j++ ) { if( gts->z( j ) && gts->z( j )->getTeamNummer() == tmp->getSpielerTeam() ) { gefunden = 1; break; } } if( gefunden ) continue; InitDatei *d = new InitDatei(); Text w; w = tmp->getSpielerTeam(); if( w.getLength() ) d->addWert( "TeamNummer", w.getText() ); if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) ) d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() ); w = tmp->getTeamFarbe(); if( w.getLength() ) d->addWert( "TeamFarbe", w.getText() ); int rundenGewonnen = 0; anz = gewinnerTeam->getEintragAnzahl(); for( int j = 0; j < anz; j++ ) { if( gewinnerTeam->hat( j ) && gewinnerTeam->get( j ) == tmp->getSpielerTeam() ) rundenGewonnen++; } w = rundenGewonnen; if( w.getLength() ) d->addWert( "GewonneneRunden", w.getText() ); int punkte = 0; int linienLength = 0; int kills = 0; int tode = 0; for( int j = 0; j < spielerAnzahl; j++ ) { Spieler *s = spieler->z( j ); if( s && s->getSpielerTeam() == tmp->getSpielerTeam() ) { punkte += s->getPunkte(); linienLength += s->getLinienLength(); kills += s->getKills(); tode += s->getTode(); } } w = punkte; if( w.getLength() ) d->addWert( "Punkte", w.getText() ); w = linienLength; if( w.getLength() ) d->addWert( "LinienLänge", w.getText() ); w = kills; if( w.getLength() ) d->addWert( "Kills", w.getText() ); w = tode; if( w.getLength() ) d->addWert( "Tode", w.getText() ); GesamtTeamStatistik *gts = new GesamtTeamStatistik(); gts->initValues( d ); this->gts->add( gts ); } } // Rundenweise int rAnz = gewinnerTeam->getEintragAnzahl(); for( int i = 0; i < rAnz; i++ ) { InitDatei *d = new InitDatei(); Text w; w = i; if( w.getLength() ) d->addWert( "RundenNummer", w.getText() ); w = rundenDauer->hat( i ) ? rundenDauer->get( i ) : -1; if( w.getLength() ) d->addWert( "RundenDauer", w.getText() ); w = gewinnerTeam->hat( i ) ? gewinnerTeam->get( i ) : -1; if( w.getLength() ) d->addWert( "SiegerTeam", w.getText() ); int spielFeldNutzung = 0; Bild *rb = rundenBild->get( i ); int *rbBuff = rb->getBuffer(); for( int j = 0; j < rb->getBreite() * rb->getHeight(); j++ ) { if( rbBuff[ j ] ) spielFeldNutzung++; } w = (int)( ( spielFeldNutzung / ( (double)( rb->getBreite() * rb->getHeight() ) / 25 ) ) * 100 ); if( w.getLength() ) d->addWert( "SpielFeldNutzung", w.getText() ); RundenRundenStatistik *rrs = new RundenRundenStatistik(); rrs->initValues( d ); rrs->setBild( rb ); // Runde Spieler for( int j = 0; j < spielerAnzahl; j++ ) { Spieler *tmp = spieler->z( j ); if( tmp ) { InitDatei *d = new InitDatei(); Text w; w = tmp->getSpielerNummer(); if( w.getLength() ) d->addWert( "SpielerNummer", w.getText() ); Text *sn = db->getAccountRufName( tmp->getAccountId() ); if( sn && sn->getLength() ) d->addWert( "SpielerName", sn->getText() ); if( sn ) sn->release(); if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) ) d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() ); w = tmp->getSpielerFarbe(); if( w.getLength() ) d->addWert( "SpielerFarbe", w.getText() ); w = tmp->getTeamFarbe(); if( w.getLength() ) d->addWert( "TeamFarbe", w.getText() ); w = tmp->getLinienLength( i ); if( w.getLength() ) d->addWert( "LinienLänge", w.getText() ); w = tmp->getKills( i ); if( w.getLength() ) d->addWert( "Kills", w.getText() ); w = tmp->getTodesZeit( i ); if( w.getLength() ) d->addWert( "Todeszeit", w.getText() ); RundenSpielerStatistik *rss = new RundenSpielerStatistik(); rss->initValues( d ); rrs->addSpielerStatistik( rss ); } } // Runde Team for( int j = 0; j < spielerAnzahl; j++ ) { Spieler *tmp = spieler->z( j ); if( tmp ) { int anz = gts->getEintragAnzahl(); bool gefunden = 0; for( int k = 0; k < anz; k++ ) { if( rrs->zTeamStatistik( k ) && rrs->zTeamStatistik( k )->getTeamNummer() == tmp->getSpielerTeam() ) { gefunden = 1; break; } } if( gefunden ) continue; InitDatei *d = new InitDatei(); Text w; w = tmp->getSpielerTeam(); if( w.getLength() ) d->addWert( "TeamNummer", w.getText() ); if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) ) d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() ); w = tmp->getTeamFarbe(); if( w.getLength() ) d->addWert( "TeamFarbe", w.getText() ); w = (int)( ( gewinnerTeam->hat( i ) ? gewinnerTeam->get( i ) : 0 ) == tmp->getSpielerTeam() ); if( w.getLength() ) d->addWert( "Ergebnis", w.getText() ); int linienLength = 0; int kills = 0; int tode = 0; for( int k = 0; k < spielerAnzahl; k++ ) { Spieler *s = spieler->z( k ); if( s && s->getSpielerTeam() == tmp->getSpielerTeam() ) { linienLength += s->getLinienLength( i ); kills += s->getKills( i ); tode += ( s->getTodesZeit( i ) != 0 ); } } w = linienLength; if( w.getLength() ) d->addWert( "LinienLänge", w.getText() ); w = kills; if( w.getLength() ) d->addWert( "Kills", w.getText() ); w = tode; if( w.getLength() ) d->addWert( "Tode", w.getText() ); RundenTeamStatistik *rts = new RundenTeamStatistik(); rts->initValues( d ); rrs->addTeamStatistik( rts ); } } this->rrs->add( rrs ); } erstellt = 1; // Statistik senden for( int i = 0; i < spielerAnzahl; i++ ) { if( sBereit->hat( i ) && sBereit->get( i ) ) sendeStatistik( i ); } // Statistik speichern Text *pfad = new Text( "../spiel log/" ); pfad->append( spielId ); pfad->append( "/fertig" ); DateiPfadErstellen( pfad ); // warten bis alle verlassen haben while( 1 ) { Sleep( 1000 ); int online = 0; for( int i = 0; i < spielerAnzahl; i++ ) online += sOnline->hat( i ) && sOnline->get( i ); if( !online ) break; } } // constant // Reference Counting StatistikV *Statistik::getThis() { ref++; return this; } StatistikV *Statistik::release() { ref--; if( !ref ) delete this; return 0; }