MinigameClient.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. #include "MinigameClient.h"
  2. #include <Klient.h>
  3. #include "Keys.h"
  4. #include <Datei.h>
  5. using namespace KSGClient;
  6. // Inhalt der MinigameClient Klasse
  7. // Konstruktor
  8. MinigameClient::MinigameClient( int klientId, unsigned short port, char *ip, char *key, unsigned char keyLen )
  9. {
  10. ref = 1;
  11. this->ip = ip;
  12. this->port = port;
  13. cId = klientId;
  14. k = 0;
  15. this->key = new char[ keyLen ];
  16. memcpy( this->key, key, keyLen );
  17. this->keyLen = keyLen;
  18. }
  19. // Destruktor
  20. MinigameClient::~MinigameClient()
  21. {
  22. trenne( 1 );
  23. delete[] key;
  24. }
  25. // verbindet sich mit dem zugewiesenen Minigame Server
  26. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  27. bool MinigameClient::verbinde()
  28. {
  29. cs.lock();
  30. if( k )
  31. {
  32. cs.unlock();
  33. return 1;
  34. }
  35. k = new Network::Klient();
  36. int l = 0;
  37. char *key;
  38. Keys::getServerKey( &key, l, Keys::MINIGAME, Keys::SENDEN );
  39. k->setSendeKey( key, l );
  40. delete[] key;
  41. Keys::getServerKey( &key, l, Keys::MINIGAME, Keys::EMPFANGEN );
  42. k->setEmpfangKey( key, l );
  43. delete[] key;
  44. if( k->verbinde( port, ip ) )
  45. {
  46. if( k->sendeEncrypted( "\1", 1 ) )
  47. {
  48. k->sendeEncrypted( (char*)&cId, 4 );
  49. char serverReturn = 0;
  50. k->getNachrichtEncrypted( &serverReturn, 1 );
  51. if( serverReturn == 3 )
  52. {
  53. char byte = 0;
  54. k->getNachrichtEncrypted( &byte, 1 );
  55. char *f = new char[ byte + 1 ];
  56. f[ byte ] = 0;
  57. k->getNachrichtEncrypted( f, byte );
  58. err = "error while identifying client Minigame Server returned: ";
  59. err += f;
  60. delete[]f;
  61. trenne( 0 );
  62. cs.unlock();
  63. return 0;
  64. }
  65. k->setSendeKey( this->key, this->keyLen );
  66. k->setEmpfangKey( this->key, this->keyLen );
  67. }
  68. else
  69. {
  70. err = "network error while sending to Minigame Server";
  71. k = k->release();
  72. cs.unlock();
  73. return 0;
  74. }
  75. }
  76. else
  77. {
  78. err = "network error while connecting to Minigame Server";
  79. k = k->release();
  80. cs.unlock();
  81. return 0;
  82. }
  83. cs.unlock();
  84. return 1;
  85. }
  86. // Gibt die Id des aktuell spielenden Accounts zurück
  87. int MinigameClient::getAccountId()
  88. {
  89. cs.lock();
  90. if( !k )
  91. {
  92. if( !verbinde() )
  93. {
  94. err = "Der Client ist nicht verbunden.";
  95. cs.unlock();
  96. return 0;
  97. }
  98. }
  99. k->sendeEncrypted( "\xB", 1 );
  100. char ret = 0;
  101. k->getNachrichtEncrypted( &ret, 1 );
  102. if( ret == 1 )
  103. {
  104. int acc = 0;
  105. k->getNachrichtEncrypted( (char*)&acc, 4 );
  106. cs.unlock();
  107. return acc;
  108. }
  109. if( ret == 3 )
  110. {
  111. char l = 0;
  112. k->getNachrichtEncrypted( &l, 1 );
  113. char *fehler = new char[ l + 1 ];
  114. fehler[ l ] = 0;
  115. k->getNachrichtEncrypted( fehler, l );
  116. err = fehler;
  117. delete[] fehler;
  118. cs.unlock();
  119. return 0;
  120. }
  121. err = "Unbekannter Fehler";
  122. cs.unlock();
  123. return 0;
  124. }
  125. // Gibt den Anzeigenamen eines bestimmten Accounts zurück
  126. // id: Die id des Accounts
  127. Text *MinigameClient::getAccountName( int id )
  128. {
  129. cs.lock();
  130. if( !k )
  131. {
  132. if( !verbinde() )
  133. {
  134. err = "Der Client ist nicht verbunden.";
  135. cs.unlock();
  136. return 0;
  137. }
  138. }
  139. k->sendeEncrypted( "\xC", 1 );
  140. char ret = 0;
  141. k->getNachrichtEncrypted( &ret, 1 );
  142. if( ret == 1 )
  143. {
  144. k->sendeEncrypted( (char*)&id, 4 );
  145. k->getNachrichtEncrypted( &ret, 1 );
  146. if( ret == 1 )
  147. {
  148. char l;
  149. k->getNachrichtEncrypted( &l, 1 );
  150. char *buff = new char[ l + 1 ];
  151. buff[ l ] = 0;
  152. k->getNachrichtEncrypted( buff, l );
  153. cs.unlock();
  154. Text *ret = new Text( buff );
  155. delete[] buff;
  156. return ret;
  157. }
  158. }
  159. if( ret == 3 )
  160. {
  161. char l = 0;
  162. k->getNachrichtEncrypted( &l, 1 );
  163. char *fehler = new char[ l + 1 ];
  164. fehler[ l ] = 0;
  165. k->getNachrichtEncrypted( fehler, l );
  166. err = fehler;
  167. delete[] fehler;
  168. cs.unlock();
  169. return 0;
  170. }
  171. err = "Unbekannter Fehler";
  172. cs.unlock();
  173. return 0;
  174. }
  175. // Gibt eine geheime zeichenkette die nur der client kennt zurück (ist bei spielstart)
  176. Text *MinigameClient::getSecret()
  177. {
  178. cs.lock();
  179. if( !k )
  180. {
  181. if( !verbinde() )
  182. {
  183. err = "Der Client ist nicht verbunden.";
  184. cs.unlock();
  185. return 0;
  186. }
  187. }
  188. k->sendeEncrypted( "\xD", 1 );
  189. char ret = 0;
  190. k->getNachrichtEncrypted( &ret, 1 );
  191. if( ret == 1 )
  192. {
  193. unsigned char l = 0;
  194. k->getNachrichtEncrypted( (char*)&l, 1 );
  195. char *buff = new char[ l + 1 ];
  196. buff[ l ] = 0;
  197. k->getNachrichtEncrypted( buff, l );
  198. cs.unlock();
  199. Text *ret = new Text( buff );
  200. delete[] buff;
  201. return ret;
  202. }
  203. if( ret == 3 )
  204. {
  205. char l = 0;
  206. k->getNachrichtEncrypted( &l, 1 );
  207. char *fehler = new char[ l + 1 ];
  208. fehler[ l ] = 0;
  209. k->getNachrichtEncrypted( fehler, l );
  210. err = fehler;
  211. delete[] fehler;
  212. cs.unlock();
  213. return 0;
  214. }
  215. err = "Unbekannter Fehler";
  216. cs.unlock();
  217. return 0;
  218. }
  219. // Ermittelt die liste mit allen Optionen zu einem Minigame zurück, zu denen es Welt beste Scores gibt
  220. // mName: Der Name des Minigames
  221. // zOptionList: Enthält nach erfolgreichem Aufruf eine Liste mit Optionen
  222. // Gibt die Anzahl der Optionen zurück
  223. int MinigameClient::getMinigameOptionList( char *mName, Framework::RCArray< Framework::Text > *zOptionList )
  224. {
  225. cs.lock();
  226. if( !k )
  227. {
  228. if( !verbinde() )
  229. {
  230. err = "Der Client ist nicht verbunden.";
  231. cs.unlock();
  232. return 0;
  233. }
  234. }
  235. k->sendeEncrypted( "\x6", 1 );
  236. char ret = 0;
  237. k->getNachrichtEncrypted( &ret, 1 );
  238. if( ret == 1 )
  239. {
  240. char l = (char)textLength( mName );
  241. k->sendeEncrypted( &l, 1 );
  242. k->sendeEncrypted( mName, l );
  243. int anz = 0;
  244. k->getNachrichtEncrypted( (char*)&anz, 4 );
  245. for( int i = 0; i < anz; i++ )
  246. {
  247. k->getNachrichtEncrypted( &l, 1 );
  248. char *option = new char[ l + 1 ];
  249. option[ l ] = 0;
  250. k->getNachrichtEncrypted( option, l );
  251. zOptionList->add( new Text( option ) );
  252. delete[] option;
  253. }
  254. cs.unlock();
  255. return anz;
  256. }
  257. if( ret == 3 )
  258. {
  259. char l = 0;
  260. k->getNachrichtEncrypted( &l, 1 );
  261. char *fehler = new char[ l + 1 ];
  262. fehler[ l ] = 0;
  263. k->getNachrichtEncrypted( fehler, l );
  264. err = fehler;
  265. delete[] fehler;
  266. cs.unlock();
  267. return 0;
  268. }
  269. err = "Unbekannter Fehler";
  270. cs.unlock();
  271. return 0;
  272. }
  273. // Ermittelt eine Liste mit den Weltbesten Scores zurück
  274. // mName: Der Name des Minigames
  275. // zScore: Enthält nach erfolgreichem Aufruf eine Liste mit Scores
  276. // zPlayerList: Enthält nach erfolgreichem Aufruf eine Liste mit angezeigten Account Namen, die die Scores erreicht haben.
  277. // zOptionList: Enthält nach erfolgreichem Aufruf eine Liste mit Optionen, die beim erreichen der Scores aktiv waren.
  278. // Gibt die Anzahl der Bestscores zurück
  279. int MinigameClient::getMinigameBestscoreList( char *mName, Framework::Array< int > *zScore, Framework::RCArray< Framework::Text > *zPlayerList, Framework::RCArray< Framework::Text > *zOptionList )
  280. {
  281. cs.lock();
  282. if( !k )
  283. {
  284. if( !verbinde() )
  285. {
  286. err = "Der Client ist nicht verbunden.";
  287. cs.unlock();
  288. return 0;
  289. }
  290. }
  291. k->sendeEncrypted( "\x7", 1 );
  292. char ret = 0;
  293. k->getNachrichtEncrypted( &ret, 1 );
  294. if( ret == 1 )
  295. {
  296. char l = (char)textLength( mName );
  297. k->sendeEncrypted( &l, 1 );
  298. k->sendeEncrypted( mName, l );
  299. int anz = 0;
  300. k->getNachrichtEncrypted( (char*)&anz, 4 );
  301. for( int i = 0; i < anz; i++ )
  302. {
  303. int score = 0;
  304. k->getNachrichtEncrypted( (char*)&score, 4 );
  305. zScore->add( score );
  306. k->getNachrichtEncrypted( &l, 1 );
  307. char *player = new char[ l + 1 ];
  308. player[ l ] = 0;
  309. k->getNachrichtEncrypted( player, l );
  310. zPlayerList->add( new Text( player ) );
  311. delete[] player;
  312. k->getNachrichtEncrypted( &l, 1 );
  313. char *option = new char[ l + 1 ];
  314. option[ l ] = 0;
  315. k->getNachrichtEncrypted( option, l );
  316. zOptionList->add( new Text( option ) );
  317. delete[] option;
  318. }
  319. cs.unlock();
  320. return anz;
  321. }
  322. if( ret == 3 )
  323. {
  324. char l = 0;
  325. k->getNachrichtEncrypted( &l, 1 );
  326. char *fehler = new char[ l + 1 ];
  327. fehler[ l ] = 0;
  328. k->getNachrichtEncrypted( fehler, l );
  329. err = fehler;
  330. delete[] fehler;
  331. cs.unlock();
  332. return 0;
  333. }
  334. err = "Unbekannter Fehler";
  335. cs.unlock();
  336. return 0;
  337. }
  338. // Gibt den Welt bestscore zu einem Bestimmten Minigame mit bestimmten Optionen zurück.
  339. // mName: Der Name des Minigames
  340. // oName: Die Optionen
  341. // zPlayer: Enthält nach erfolgreichem Aufruf den Angezeigten Namen des Accounts, der den Score erreicht hat
  342. int MinigameClient::getMinigameOptionBestscore( char *mName, char *oName, Framework::Text *zPlayer )
  343. {
  344. cs.lock();
  345. if( !k )
  346. {
  347. if( !verbinde() )
  348. {
  349. err = "Der Client ist nicht verbunden.";
  350. cs.unlock();
  351. return 0;
  352. }
  353. }
  354. k->sendeEncrypted( "\x8", 1 );
  355. char ret = 0;
  356. k->getNachrichtEncrypted( &ret, 1 );
  357. if( ret == 1 )
  358. {
  359. char l = (char)textLength( mName );
  360. k->sendeEncrypted( &l, 1 );
  361. k->sendeEncrypted( mName, l );
  362. l = (char)textLength( oName );
  363. k->sendeEncrypted( &l, 1 );
  364. k->sendeEncrypted( oName, l );
  365. int score = 0;
  366. k->getNachrichtEncrypted( (char*)&score, 4 );
  367. k->getNachrichtEncrypted( &l, 1 );
  368. char *player = new char[ l + 1 ];
  369. player[ l ] = 0;
  370. k->getNachrichtEncrypted( player, l );
  371. zPlayer->setText( player );
  372. delete[] player;
  373. cs.unlock();
  374. return score;
  375. }
  376. if( ret == 3 )
  377. {
  378. char l = 0;
  379. k->getNachrichtEncrypted( &l, 1 );
  380. char *fehler = new char[ l + 1 ];
  381. fehler[ l ] = 0;
  382. k->getNachrichtEncrypted( fehler, l );
  383. err = fehler;
  384. delete[] fehler;
  385. cs.unlock();
  386. return 0;
  387. }
  388. err = "Unbekannter Fehler";
  389. cs.unlock();
  390. return 0;
  391. }
  392. // Meldet die Beendigung eines Minigames
  393. // mName: Der Name des Minigames
  394. // oName: Die Optionen mit denen gespielt wurde
  395. // score: Der Erreichte Score
  396. // zCapture: Ein Zeiger auf eine Datei mit der Spielaufzeichnung
  397. // Gibt 0 zurück wenn eines Fehler aufgetreten ist, 1 wenn der Forgang erfolgreich war
  398. bool MinigameClient::reportEndOfGame( char *mName, char *oName, int score, Framework::Datei *zCapture )
  399. {
  400. cs.lock();
  401. if( !k )
  402. {
  403. if( !verbinde() )
  404. {
  405. err = "Der Client ist nicht verbunden.";
  406. cs.unlock();
  407. return 0;
  408. }
  409. }
  410. k->sendeEncrypted( "\x9", 1 );
  411. char ret = 0;
  412. k->getNachrichtEncrypted( &ret, 1 );
  413. if( ret == 1 )
  414. {
  415. char l = (char)textLength( mName );
  416. k->sendeEncrypted( &l, 1 );
  417. k->sendeEncrypted( mName, l );
  418. l = (char)textLength( oName );
  419. k->sendeEncrypted( &l, 1 );
  420. k->sendeEncrypted( oName, l );
  421. k->sendeEncrypted( (char*)&score, 4 );
  422. k->getNachrichtEncrypted( &ret, 1 );
  423. if( ret == 1 )
  424. {
  425. int size = (int)zCapture->getSize();
  426. if( !zCapture->istOffen() )
  427. zCapture->open( Datei::Style::lesen );
  428. k->sendeEncrypted( (char*)&size, 4 );
  429. char *buffer = new char[ 2048 ];
  430. while( size > 0 )
  431. {
  432. int l = size > 2048 ? 2048 : size;
  433. zCapture->lese( buffer, l );
  434. k->sendeEncrypted( buffer, l );
  435. size -= l;
  436. }
  437. delete[] buffer;
  438. zCapture->close();
  439. cs.unlock();
  440. return 1;
  441. }
  442. else if( ret == 0 )
  443. {
  444. cs.unlock();
  445. return 1;
  446. }
  447. }
  448. if( ret == 3 )
  449. {
  450. char l = 0;
  451. k->getNachrichtEncrypted( &l, 1 );
  452. char *fehler = new char[ l + 1 ];
  453. fehler[ l ] = 0;
  454. k->getNachrichtEncrypted( fehler, l );
  455. err = fehler;
  456. delete[] fehler;
  457. cs.unlock();
  458. return 0;
  459. }
  460. err = "Unbekannter Fehler";
  461. cs.unlock();
  462. return 0;
  463. }
  464. // Lädt ein Game Capture herunter und speichert sie unter data/tmp/minigames/wb.mgc
  465. // mName: Der Name des Minigames
  466. // oName: Die Optionen
  467. // Gibt die Datei mit dem Capture zurück
  468. Framework::Datei *MinigameClient::downloadGameCapture( char *mName, char *oName )
  469. {
  470. cs.lock();
  471. if( !k )
  472. {
  473. if( !verbinde() )
  474. {
  475. err = "Der Client ist nicht verbunden.";
  476. cs.unlock();
  477. return 0;
  478. }
  479. }
  480. k->sendeEncrypted( "\xA", 1 );
  481. char ret = 0;
  482. k->getNachrichtEncrypted( &ret, 1 );
  483. if( ret == 1 )
  484. {
  485. char l = (char)textLength( mName );
  486. k->sendeEncrypted( &l, 1 );
  487. k->sendeEncrypted( mName, l );
  488. l = (char)textLength( oName );
  489. k->sendeEncrypted( &l, 1 );
  490. k->sendeEncrypted( oName, l );
  491. k->getNachrichtEncrypted( &ret, 1 );
  492. if( ret == 1 )
  493. {
  494. Datei *capture = new Datei();
  495. capture->setDatei( "data/tmp/minigames/wb.mgc" );
  496. capture->erstellen();
  497. capture->open( Datei::Style::schreiben );
  498. int size = 0;
  499. k->getNachrichtEncrypted( (char*)&size, 4 );
  500. char *buffer = new char[ 2048 ];
  501. while( size > 0 )
  502. {
  503. int l = size > 2048 ? 2048 : size;
  504. k->getNachrichtEncrypted( buffer, l );
  505. capture->schreibe( buffer, l );
  506. size -= l;
  507. }
  508. delete[] buffer;
  509. capture->close();
  510. cs.unlock();
  511. return capture;
  512. }
  513. err = "Unbekannter Fehler";
  514. cs.unlock();
  515. return 0;
  516. }
  517. if( ret == 3 )
  518. {
  519. char l = 0;
  520. k->getNachrichtEncrypted( &l, 1 );
  521. char *fehler = new char[ l + 1 ];
  522. fehler[ l ] = 0;
  523. k->getNachrichtEncrypted( fehler, l );
  524. err = fehler;
  525. delete[] fehler;
  526. cs.unlock();
  527. return 0;
  528. }
  529. err = "Unbekannter Fehler";
  530. cs.unlock();
  531. return 0;
  532. }
  533. // Erhält die Verbindung aufrecht
  534. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  535. // Sollte während einer bestehenden Verbindung etwa einmal alle 60 Sekunden aufgerufen werden, da sonst der Router die Verbindung automatisch trennt
  536. bool MinigameClient::keepAlive()
  537. {
  538. char res = 0;
  539. if( !cs.tryLock() )
  540. return 1;
  541. if( !k )
  542. {
  543. err = "Der Client ist nicht verbunden.";
  544. cs.unlock();
  545. return 0;
  546. }
  547. bool ok = k->sendeEncrypted( "\x5", 1 );
  548. ok &= k->getNachrichtEncrypted( &res, 1 );
  549. cs.unlock();
  550. if( res != 1 || !ok )
  551. trenne( 0 );
  552. return res == 1;
  553. }
  554. // Trennt die Verbindung zum Server
  555. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  556. // Sollte erst nach einem erfolgreichen Aufruf von verbinde aufgerufen werden
  557. bool MinigameClient::trenne( bool abmelden )
  558. {
  559. cs.lock();
  560. verbinde();
  561. if( !k )
  562. {
  563. cs.unlock();
  564. return 1;
  565. }
  566. if( abmelden )
  567. {
  568. k->sendeEncrypted( "\4", 1 );
  569. char ret = 0;
  570. k->getNachrichtEncrypted( &ret, 1 );
  571. if( ret == 3 )
  572. { // error
  573. k->getNachrichtEncrypted( &ret, 1 );
  574. char *msg = new char[ ret + 1 ];
  575. msg[ ret ] = 0;
  576. if( ret )
  577. k->getNachrichtEncrypted( msg, ret );
  578. err = "error while unregister Client Minigame Server returned: ";
  579. err += msg;
  580. delete[] msg;
  581. }
  582. }
  583. k->sendeEncrypted( "\3", 1 );
  584. char ret = 0;
  585. k->getNachrichtEncrypted( &ret, 1 );
  586. if( ret == 3 )
  587. { // error
  588. k->getNachrichtEncrypted( &ret, 1 );
  589. char *msg = new char[ ret + 1 ];
  590. msg[ ret ] = 0;
  591. if( ret )
  592. k->getNachrichtEncrypted( msg, ret );
  593. err = "error while trenne Minigame Server returned: ";
  594. err += msg;
  595. delete[] msg;
  596. }
  597. k->trenne();
  598. k = k->release();
  599. cs.unlock();
  600. return 1;
  601. }
  602. // Gibt 1 zurück, falls der Client verbunden ist, 0 sonst
  603. bool MinigameClient::istVerbunden() const
  604. {
  605. return k != 0;
  606. }
  607. // gibt den Letzten Fehlertext zuück
  608. // sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist
  609. char *MinigameClient::getLetzterFehler() const
  610. {
  611. return err;
  612. }
  613. // Erhöht den Reference Counter um 1 un gibt this zurück
  614. MinigameServerClient *MinigameClient::getThis()
  615. {
  616. ref++;
  617. return this;
  618. }
  619. // Verringert den Reference Counter um 1 und gibt 0 zurück.
  620. // Falls der Reference Counter nach dem Aufruf auf 0 ist löscht sich das Objekt selbst
  621. MinigameServerClient *MinigameClient::release()
  622. {
  623. if( !--ref )
  624. delete this;
  625. return 0;
  626. }