Statistik.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. #include "Statistik.h"
  2. #include <DateiSystem.h>
  3. #include <Datei.h>
  4. #ifndef WIN32
  5. #include <unistd.h>
  6. #define Sleep( x ) usleep( (x) * 1000 )
  7. #endif
  8. // Inhalt der Statistik Klasse aus Statistik.h
  9. // Konstruktor
  10. Statistik::Statistik()
  11. {
  12. spielId = 0;
  13. karteId = 0;
  14. db = 0;
  15. spielerAnzahl = 0;
  16. spieler = new RCArray< Spieler >();
  17. erstellt = 0;
  18. sOnline = new Array< bool >();
  19. sBereit = new Array< bool >();
  20. gss = new RCArray< GesamtSpielerStatistik >();
  21. gts = new RCArray< GesamtTeamStatistik >();
  22. rrs = new RCArray< RundenRundenStatistik >();
  23. teamNamen = 0;
  24. gewinnerTeam = new Array< int >();
  25. rundenDauer = new Array< int >();
  26. rundenBild = new RCArray< Bild >();
  27. ref = 1;
  28. }
  29. // Destruktor
  30. Statistik::~Statistik()
  31. {
  32. if( db )
  33. db->release();
  34. spieler->release();
  35. sOnline->release();
  36. sBereit->release();
  37. gss->release();
  38. gts->release();
  39. rrs->release();
  40. if( teamNamen )
  41. teamNamen->release();
  42. gewinnerTeam->release();
  43. rundenDauer->release();
  44. rundenBild->release();
  45. }
  46. // privat
  47. void Statistik::sendeStatistik( int index )
  48. { // Sendet Statistik an Spieler index
  49. if( !sOnline->hat( index ) || !sOnline->get( index ) )
  50. return;
  51. Klient *zk = spieler->z( index )->zKlient();
  52. if( !zk )
  53. return;
  54. int anz = gss->getEintragAnzahl();
  55. for( int i = 0; i < anz; i++ )
  56. zk->sendeGesamtSpielerStatistik( gss->z( i ) );
  57. anz = gts->getEintragAnzahl();
  58. for( int i = 0; i < anz; i++ )
  59. zk->sendeGesamtTeamStatistik( gts->z( i ) );
  60. anz = rrs->getEintragAnzahl();
  61. for( int i = 0; i < anz; i++ )
  62. zk->sendeRundeStatistik( rrs->z( i ) );
  63. zk->sendeStatistikLadenFertig();
  64. for( int i = 0; i < spielerAnzahl; i++ )
  65. {
  66. if( !sOnline->hat( i ) || !sOnline->get( i ) )
  67. zk->sendeStatistikSpielerOffline( spieler->z( i )->getAccountId() );
  68. }
  69. }
  70. // nicht constant
  71. void Statistik::setSpielId( int id )
  72. {
  73. spielId = id;
  74. }
  75. void Statistik::setKarteId( int id )
  76. {
  77. karteId = id;
  78. }
  79. void Statistik::setPSQLDB( SSDatenbankV *db )
  80. {
  81. if( this->db )
  82. this->db->release();
  83. this->db = db;
  84. }
  85. void Statistik::setTeamNamen( RCArray< Text > *namen )
  86. {
  87. if( teamNamen )
  88. teamNamen->release();
  89. teamNamen = namen;
  90. }
  91. void Statistik::rundenEnde( int team, int dauer, Bild *b )
  92. {
  93. gewinnerTeam->add( team );
  94. rundenDauer->add( dauer );
  95. Bild *rb = new Bild();
  96. rb->neuBild( b->getBreite(), b->getHeight(), 0 );
  97. rb->drawBild( 0, 0, rb->getBreite(), rb->getHeight(), *b );
  98. rundenBild->add( rb );
  99. b->release();
  100. }
  101. void Statistik::setSpieler( int anzahl, RCArray< Spieler > *zSpieler )
  102. {
  103. spielerAnzahl = anzahl;
  104. for( int i = 0; i < anzahl; i++ )
  105. {
  106. spieler->set( zSpieler->get( i ), i );
  107. sOnline->set( 0, i );
  108. sBereit->set( 0, i );
  109. }
  110. }
  111. void Statistik::klientOffline( int accountId )
  112. {
  113. for( int i = 0; i < spielerAnzahl; i++ )
  114. {
  115. if( spieler->z( i )->getAccountId() == accountId )
  116. {
  117. sOnline->set( 0, i );
  118. sBereit->set( 0, i );
  119. }
  120. else if( sOnline->hat( i ) && sOnline->get( i ) && spieler->z( i )->zKlient() )
  121. spieler->z( i )->zKlient()->sendeStatistikSpielerOffline( accountId );
  122. }
  123. }
  124. void Statistik::statistikAnfrage( int accountId, short len, char *bytes )
  125. {
  126. len--;
  127. switch( *bytes )
  128. {
  129. case 1: // Spieler ist Bereit
  130. for( int i = 0; i < spielerAnzahl; i++ )
  131. {
  132. if( !erstellt )
  133. {
  134. if( spieler->z( i )->getAccountId() == accountId )
  135. sBereit->set( 1, i );
  136. }
  137. else if( spieler->z( i )->getAccountId() == accountId )
  138. {
  139. sendeStatistik( i );
  140. break;
  141. }
  142. }
  143. break;
  144. case 2: // Chat Nachricht
  145. bytes++;
  146. char *txt = new char[ len + 1 ];
  147. txt[ len ] = 0;
  148. for( int i = 0; i < len; i++ )
  149. txt[ i ] = bytes[ i ];
  150. for( int i = 0; i < spielerAnzahl; i++ )
  151. {
  152. if( sOnline->hat( i ) && sOnline->get( i ) && spieler->z( i )->zKlient() )
  153. spieler->z( i )->zKlient()->sendeStatistikChatNachricht( accountId, txt );
  154. }
  155. delete[] txt;
  156. break;
  157. }
  158. }
  159. void Statistik::run()
  160. {
  161. for( int i = 0; i < spielerAnzahl; i++ )
  162. sOnline->set( spieler->z( i )->istOnline(), i );
  163. // Statistik erstellen
  164. // gesammt Spieler
  165. for( int i = 0; i < spielerAnzahl; i++ )
  166. {
  167. if( spieler->z( i ) )
  168. {
  169. Spieler *tmp = spieler->z( i );
  170. InitDatei *d = new InitDatei();
  171. Text w;
  172. w = tmp->getSpielerNummer();
  173. if( w.getLength() )
  174. d->addWert( "SpielerNummer", w.getText() );
  175. Text *sn = db->getAccountRufName( tmp->getAccountId() );
  176. if( sn && sn->getLength() )
  177. d->addWert( "SpielerName", sn->getText() );
  178. if( sn )
  179. sn->release();
  180. if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) )
  181. d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() );
  182. w = tmp->getSpielerFarbe();
  183. if( w.getLength() )
  184. d->addWert( "SpielerFarbe", w.getText() );
  185. w = tmp->getTeamFarbe();
  186. if( w.getLength() )
  187. d->addWert( "TeamFarbe", w.getText() );
  188. w = tmp->getRundenGewonnen();
  189. if( w.getLength() )
  190. d->addWert( "GewonneneRunden", w.getText() );
  191. w = tmp->getPunkte();
  192. if( w.getLength() )
  193. d->addWert( "Punkte", w.getText() );
  194. w = tmp->getLinienLength();
  195. if( w.getLength() )
  196. d->addWert( "LinienLänge", w.getText() );
  197. w = tmp->getZeitAmLeben();
  198. if( w.getLength() )
  199. d->addWert( "ZeitAmLeben", w.getText() );
  200. w = tmp->getZeitTod();
  201. if( w.getLength() )
  202. d->addWert( "ZeitTod", w.getText() );
  203. w = tmp->getKills();
  204. if( w.getLength() )
  205. d->addWert( "Kills", w.getText() );
  206. w = tmp->getTode();
  207. if( w.getLength() )
  208. d->addWert( "Tode", w.getText() );
  209. GesamtSpielerStatistik *gss = new GesamtSpielerStatistik();
  210. gss->initValues( d );
  211. this->gss->add( gss );
  212. }
  213. }
  214. // Gesamt Team
  215. for( int i = 0; i < spielerAnzahl; i++ )
  216. {
  217. Spieler *tmp = spieler->z( i );
  218. if( tmp )
  219. {
  220. int anz = gts->getEintragAnzahl();
  221. bool gefunden = 0;
  222. for( int j = 0; j < anz; j++ )
  223. {
  224. if( gts->z( j ) && gts->z( j )->getTeamNummer() == tmp->getSpielerTeam() )
  225. {
  226. gefunden = 1;
  227. break;
  228. }
  229. }
  230. if( gefunden )
  231. continue;
  232. InitDatei *d = new InitDatei();
  233. Text w;
  234. w = tmp->getSpielerTeam();
  235. if( w.getLength() )
  236. d->addWert( "TeamNummer", w.getText() );
  237. if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) )
  238. d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() );
  239. w = tmp->getTeamFarbe();
  240. if( w.getLength() )
  241. d->addWert( "TeamFarbe", w.getText() );
  242. int rundenGewonnen = 0;
  243. anz = gewinnerTeam->getEintragAnzahl();
  244. for( int j = 0; j < anz; j++ )
  245. {
  246. if( gewinnerTeam->hat( j ) && gewinnerTeam->get( j ) == tmp->getSpielerTeam() )
  247. rundenGewonnen++;
  248. }
  249. w = rundenGewonnen;
  250. if( w.getLength() )
  251. d->addWert( "GewonneneRunden", w.getText() );
  252. int punkte = 0;
  253. int linienLength = 0;
  254. int kills = 0;
  255. int tode = 0;
  256. for( int j = 0; j < spielerAnzahl; j++ )
  257. {
  258. Spieler *s = spieler->z( j );
  259. if( s && s->getSpielerTeam() == tmp->getSpielerTeam() )
  260. {
  261. punkte += s->getPunkte();
  262. linienLength += s->getLinienLength();
  263. kills += s->getKills();
  264. tode += s->getTode();
  265. }
  266. }
  267. w = punkte;
  268. if( w.getLength() )
  269. d->addWert( "Punkte", w.getText() );
  270. w = linienLength;
  271. if( w.getLength() )
  272. d->addWert( "LinienLänge", w.getText() );
  273. w = kills;
  274. if( w.getLength() )
  275. d->addWert( "Kills", w.getText() );
  276. w = tode;
  277. if( w.getLength() )
  278. d->addWert( "Tode", w.getText() );
  279. GesamtTeamStatistik *gts = new GesamtTeamStatistik();
  280. gts->initValues( d );
  281. this->gts->add( gts );
  282. }
  283. }
  284. // Rundenweise
  285. int rAnz = gewinnerTeam->getEintragAnzahl();
  286. for( int i = 0; i < rAnz; i++ )
  287. {
  288. InitDatei *d = new InitDatei();
  289. Text w;
  290. w = i;
  291. if( w.getLength() )
  292. d->addWert( "RundenNummer", w.getText() );
  293. w = rundenDauer->hat( i ) ? rundenDauer->get( i ) : -1;
  294. if( w.getLength() )
  295. d->addWert( "RundenDauer", w.getText() );
  296. w = gewinnerTeam->hat( i ) ? gewinnerTeam->get( i ) : -1;
  297. if( w.getLength() )
  298. d->addWert( "SiegerTeam", w.getText() );
  299. int spielFeldNutzung = 0;
  300. Bild *rb = rundenBild->get( i );
  301. int *rbBuff = rb->getBuffer();
  302. for( int j = 0; j < rb->getBreite() * rb->getHeight(); j++ )
  303. {
  304. if( rbBuff[ j ] )
  305. spielFeldNutzung++;
  306. }
  307. w = (int)( ( spielFeldNutzung / ( (double)( rb->getBreite() * rb->getHeight() ) / 25 ) ) * 100 );
  308. if( w.getLength() )
  309. d->addWert( "SpielFeldNutzung", w.getText() );
  310. RundenRundenStatistik *rrs = new RundenRundenStatistik();
  311. rrs->initValues( d );
  312. rrs->setBild( rb );
  313. // Runde Spieler
  314. for( int j = 0; j < spielerAnzahl; j++ )
  315. {
  316. Spieler *tmp = spieler->z( j );
  317. if( tmp )
  318. {
  319. InitDatei *d = new InitDatei();
  320. Text w;
  321. w = tmp->getSpielerNummer();
  322. if( w.getLength() )
  323. d->addWert( "SpielerNummer", w.getText() );
  324. Text *sn = db->getAccountRufName( tmp->getAccountId() );
  325. if( sn && sn->getLength() )
  326. d->addWert( "SpielerName", sn->getText() );
  327. if( sn )
  328. sn->release();
  329. if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) )
  330. d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() );
  331. w = tmp->getSpielerFarbe();
  332. if( w.getLength() )
  333. d->addWert( "SpielerFarbe", w.getText() );
  334. w = tmp->getTeamFarbe();
  335. if( w.getLength() )
  336. d->addWert( "TeamFarbe", w.getText() );
  337. w = tmp->getLinienLength( i );
  338. if( w.getLength() )
  339. d->addWert( "LinienLänge", w.getText() );
  340. w = tmp->getKills( i );
  341. if( w.getLength() )
  342. d->addWert( "Kills", w.getText() );
  343. w = tmp->getTodesZeit( i );
  344. if( w.getLength() )
  345. d->addWert( "Todeszeit", w.getText() );
  346. RundenSpielerStatistik *rss = new RundenSpielerStatistik();
  347. rss->initValues( d );
  348. rrs->addSpielerStatistik( rss );
  349. }
  350. }
  351. // Runde Team
  352. for( int j = 0; j < spielerAnzahl; j++ )
  353. {
  354. Spieler *tmp = spieler->z( j );
  355. if( tmp )
  356. {
  357. int anz = gts->getEintragAnzahl();
  358. bool gefunden = 0;
  359. for( int k = 0; k < anz; k++ )
  360. {
  361. if( rrs->zTeamStatistik( k ) && rrs->zTeamStatistik( k )->getTeamNummer() == tmp->getSpielerTeam() )
  362. {
  363. gefunden = 1;
  364. break;
  365. }
  366. }
  367. if( gefunden )
  368. continue;
  369. InitDatei *d = new InitDatei();
  370. Text w;
  371. w = tmp->getSpielerTeam();
  372. if( w.getLength() )
  373. d->addWert( "TeamNummer", w.getText() );
  374. if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) )
  375. d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() );
  376. w = tmp->getTeamFarbe();
  377. if( w.getLength() )
  378. d->addWert( "TeamFarbe", w.getText() );
  379. w = (int)( ( gewinnerTeam->hat( i ) ? gewinnerTeam->get( i ) : 0 ) == tmp->getSpielerTeam() );
  380. if( w.getLength() )
  381. d->addWert( "Ergebnis", w.getText() );
  382. int linienLength = 0;
  383. int kills = 0;
  384. int tode = 0;
  385. for( int k = 0; k < spielerAnzahl; k++ )
  386. {
  387. Spieler *s = spieler->z( k );
  388. if( s && s->getSpielerTeam() == tmp->getSpielerTeam() )
  389. {
  390. linienLength += s->getLinienLength( i );
  391. kills += s->getKills( i );
  392. tode += ( s->getTodesZeit( i ) != 0 );
  393. }
  394. }
  395. w = linienLength;
  396. if( w.getLength() )
  397. d->addWert( "LinienLänge", w.getText() );
  398. w = kills;
  399. if( w.getLength() )
  400. d->addWert( "Kills", w.getText() );
  401. w = tode;
  402. if( w.getLength() )
  403. d->addWert( "Tode", w.getText() );
  404. RundenTeamStatistik *rts = new RundenTeamStatistik();
  405. rts->initValues( d );
  406. rrs->addTeamStatistik( rts );
  407. }
  408. }
  409. this->rrs->add( rrs );
  410. }
  411. erstellt = 1;
  412. // Statistik senden
  413. for( int i = 0; i < spielerAnzahl; i++ )
  414. {
  415. if( sBereit->hat( i ) && sBereit->get( i ) )
  416. sendeStatistik( i );
  417. }
  418. // Statistik speichern
  419. Text *pfad = new Text( "../spiel log/" );
  420. pfad->append( spielId );
  421. pfad->append( "/fertig" );
  422. DateiPfadErstellen( pfad );
  423. // warten bis alle verlassen haben
  424. while( 1 )
  425. {
  426. Sleep( 1000 );
  427. int online = 0;
  428. for( int i = 0; i < spielerAnzahl; i++ )
  429. online += sOnline->hat( i ) && sOnline->get( i );
  430. if( !online )
  431. break;
  432. }
  433. }
  434. // constant
  435. // Reference Counting
  436. StatistikV *Statistik::getThis()
  437. {
  438. ref++;
  439. return this;
  440. }
  441. StatistikV *Statistik::release()
  442. {
  443. ref--;
  444. if( !ref )
  445. delete this;
  446. return 0;
  447. }