MinigameClient.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  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. // Ermittelt die liste mit allen Optionen zu einem Minigame zurück, zu denen es Welt beste Scores gibt
  176. // mName: Der Name des Minigames
  177. // zOptionList: Enthält nach erfolgreichem Aufruf eine Liste mit Optionen
  178. // Gibt die Anzahl der Optionen zurück
  179. int MinigameClient::getMinigameOptionList( char *mName, Framework::RCArray< Framework::Text > *zOptionList )
  180. {
  181. cs.lock();
  182. if( !k )
  183. {
  184. if( !verbinde() )
  185. {
  186. err = "Der Client ist nicht verbunden.";
  187. cs.unlock();
  188. return 0;
  189. }
  190. }
  191. k->sendeEncrypted( "\x6", 1 );
  192. char ret = 0;
  193. k->getNachrichtEncrypted( &ret, 1 );
  194. if( ret == 1 )
  195. {
  196. char l = (char)textLength( mName );
  197. k->sendeEncrypted( &l, 1 );
  198. k->sendeEncrypted( mName, l );
  199. int anz = 0;
  200. k->getNachrichtEncrypted( (char*)&anz, 4 );
  201. for( int i = 0; i < anz; i++ )
  202. {
  203. k->getNachrichtEncrypted( &l, 1 );
  204. char *option = new char[ l + 1 ];
  205. option[ l ] = 0;
  206. k->getNachrichtEncrypted( option, l );
  207. zOptionList->add( new Text( option ) );
  208. delete[] option;
  209. }
  210. cs.unlock();
  211. return anz;
  212. }
  213. if( ret == 3 )
  214. {
  215. char l = 0;
  216. k->getNachrichtEncrypted( &l, 1 );
  217. char *fehler = new char[ l + 1 ];
  218. fehler[ l ] = 0;
  219. k->getNachrichtEncrypted( fehler, l );
  220. err = fehler;
  221. delete[] fehler;
  222. cs.unlock();
  223. return 0;
  224. }
  225. err = "Unbekannter Fehler";
  226. cs.unlock();
  227. return 0;
  228. }
  229. // Ermittelt eine Liste mit den Weltbesten Scores zurück
  230. // mName: Der Name des Minigames
  231. // zScore: Enthält nach erfolgreichem Aufruf eine Liste mit Scores
  232. // zPlayerList: Enthält nach erfolgreichem Aufruf eine Liste mit angezeigten Account Namen, die die Scores erreicht haben.
  233. // zOptionList: Enthält nach erfolgreichem Aufruf eine Liste mit Optionen, die beim erreichen der Scores aktiv waren.
  234. // Gibt die Anzahl der Bestscores zurück
  235. int MinigameClient::getMinigameBestscoreList( char *mName, Framework::Array< int > *zScore, Framework::RCArray< Framework::Text > *zPlayerList, Framework::RCArray< Framework::Text > *zOptionList )
  236. {
  237. cs.lock();
  238. if( !k )
  239. {
  240. if( !verbinde() )
  241. {
  242. err = "Der Client ist nicht verbunden.";
  243. cs.unlock();
  244. return 0;
  245. }
  246. }
  247. k->sendeEncrypted( "\x7", 1 );
  248. char ret = 0;
  249. k->getNachrichtEncrypted( &ret, 1 );
  250. if( ret == 1 )
  251. {
  252. char l = (char)textLength( mName );
  253. k->sendeEncrypted( &l, 1 );
  254. k->sendeEncrypted( mName, l );
  255. int anz = 0;
  256. k->getNachrichtEncrypted( (char*)&anz, 4 );
  257. for( int i = 0; i < anz; i++ )
  258. {
  259. int score = 0;
  260. k->getNachrichtEncrypted( (char*)&score, 4 );
  261. zScore->add( score );
  262. k->getNachrichtEncrypted( &l, 1 );
  263. char *player = new char[ l + 1 ];
  264. player[ l ] = 0;
  265. k->getNachrichtEncrypted( player, l );
  266. zPlayerList->add( new Text( player ) );
  267. delete[] player;
  268. k->getNachrichtEncrypted( &l, 1 );
  269. char *option = new char[ l + 1 ];
  270. option[ l ] = 0;
  271. k->getNachrichtEncrypted( option, l );
  272. zOptionList->add( new Text( option ) );
  273. delete[] option;
  274. }
  275. cs.unlock();
  276. return anz;
  277. }
  278. if( ret == 3 )
  279. {
  280. char l = 0;
  281. k->getNachrichtEncrypted( &l, 1 );
  282. char *fehler = new char[ l + 1 ];
  283. fehler[ l ] = 0;
  284. k->getNachrichtEncrypted( fehler, l );
  285. err = fehler;
  286. delete[] fehler;
  287. cs.unlock();
  288. return 0;
  289. }
  290. err = "Unbekannter Fehler";
  291. cs.unlock();
  292. return 0;
  293. }
  294. // Gibt den Welt bestscore zu einem Bestimmten Minigame mit bestimmten Optionen zurück.
  295. // mName: Der Name des Minigames
  296. // oName: Die Optionen
  297. // zPlayer: Enthält nach erfolgreichem Aufruf den Angezeigten Namen des Accounts, der den Score erreicht hat
  298. int MinigameClient::getMinigameOptionBestscore( char *mName, char *oName, Framework::Text *zPlayer )
  299. {
  300. cs.lock();
  301. if( !k )
  302. {
  303. if( !verbinde() )
  304. {
  305. err = "Der Client ist nicht verbunden.";
  306. cs.unlock();
  307. return 0;
  308. }
  309. }
  310. k->sendeEncrypted( "\x8", 1 );
  311. char ret = 0;
  312. k->getNachrichtEncrypted( &ret, 1 );
  313. if( ret == 1 )
  314. {
  315. char l = (char)textLength( mName );
  316. k->sendeEncrypted( &l, 1 );
  317. k->sendeEncrypted( mName, l );
  318. l = (char)textLength( oName );
  319. k->sendeEncrypted( &l, 1 );
  320. k->sendeEncrypted( oName, l );
  321. int score = 0;
  322. k->getNachrichtEncrypted( (char*)&score, 4 );
  323. k->getNachrichtEncrypted( &l, 1 );
  324. char *player = new char[ l + 1 ];
  325. player[ l ] = 0;
  326. k->getNachrichtEncrypted( player, l );
  327. zPlayer->setText( player );
  328. delete[] player;
  329. cs.unlock();
  330. return score;
  331. }
  332. if( ret == 3 )
  333. {
  334. char l = 0;
  335. k->getNachrichtEncrypted( &l, 1 );
  336. char *fehler = new char[ l + 1 ];
  337. fehler[ l ] = 0;
  338. k->getNachrichtEncrypted( fehler, l );
  339. err = fehler;
  340. delete[] fehler;
  341. cs.unlock();
  342. return 0;
  343. }
  344. err = "Unbekannter Fehler";
  345. cs.unlock();
  346. return 0;
  347. }
  348. // Meldet die Beendigung eines Minigames
  349. // mName: Der Name des Minigames
  350. // oName: Die Optionen mit denen gespielt wurde
  351. // score: Der Erreichte Score
  352. // zCapture: Ein Zeiger auf eine Datei mit der Spielaufzeichnung
  353. // Gibt 0 zurück wenn eines Fehler aufgetreten ist, 1 wenn der Forgang erfolgreich war
  354. bool MinigameClient::reportEndOfGame( char *mName, char *oName, int score, Framework::Datei *zCapture )
  355. {
  356. cs.lock();
  357. if( !k )
  358. {
  359. if( !verbinde() )
  360. {
  361. err = "Der Client ist nicht verbunden.";
  362. cs.unlock();
  363. return 0;
  364. }
  365. }
  366. k->sendeEncrypted( "\x9", 1 );
  367. char ret = 0;
  368. k->getNachrichtEncrypted( &ret, 1 );
  369. if( ret == 1 )
  370. {
  371. char l = (char)textLength( mName );
  372. k->sendeEncrypted( &l, 1 );
  373. k->sendeEncrypted( mName, l );
  374. l = (char)textLength( oName );
  375. k->sendeEncrypted( &l, 1 );
  376. k->sendeEncrypted( oName, l );
  377. k->sendeEncrypted( (char*)&score, 4 );
  378. k->getNachrichtEncrypted( &ret, 1 );
  379. if( ret == 1 )
  380. {
  381. int size = (int)zCapture->getSize();
  382. if( !zCapture->istOffen() )
  383. zCapture->open( Datei::Style::lesen );
  384. k->sendeEncrypted( (char*)&size, 4 );
  385. char *buffer = new char[ 2048 ];
  386. while( size > 0 )
  387. {
  388. int l = size > 2048 ? 2048 : size;
  389. zCapture->lese( buffer, l );
  390. k->sendeEncrypted( buffer, l );
  391. size -= l;
  392. }
  393. delete[] buffer;
  394. zCapture->close();
  395. cs.unlock();
  396. return 1;
  397. }
  398. else if( ret == 0 )
  399. {
  400. cs.unlock();
  401. return 1;
  402. }
  403. }
  404. if( ret == 3 )
  405. {
  406. char l = 0;
  407. k->getNachrichtEncrypted( &l, 1 );
  408. char *fehler = new char[ l + 1 ];
  409. fehler[ l ] = 0;
  410. k->getNachrichtEncrypted( fehler, l );
  411. err = fehler;
  412. delete[] fehler;
  413. cs.unlock();
  414. return 0;
  415. }
  416. err = "Unbekannter Fehler";
  417. cs.unlock();
  418. return 0;
  419. }
  420. // Lädt ein Game Capture herunter und speichert sie unter data/tmp/minigames/wb.mgc
  421. // mName: Der Name des Minigames
  422. // oName: Die Optionen
  423. // Gibt die Datei mit dem Capture zurück
  424. Framework::Datei *MinigameClient::downloadGameCapture( char *mName, char *oName )
  425. {
  426. cs.lock();
  427. if( !k )
  428. {
  429. if( !verbinde() )
  430. {
  431. err = "Der Client ist nicht verbunden.";
  432. cs.unlock();
  433. return 0;
  434. }
  435. }
  436. k->sendeEncrypted( "\xA", 1 );
  437. char ret = 0;
  438. k->getNachrichtEncrypted( &ret, 1 );
  439. if( ret == 1 )
  440. {
  441. char l = (char)textLength( mName );
  442. k->sendeEncrypted( &l, 1 );
  443. k->sendeEncrypted( mName, l );
  444. l = (char)textLength( oName );
  445. k->sendeEncrypted( &l, 1 );
  446. k->sendeEncrypted( oName, l );
  447. k->getNachrichtEncrypted( &ret, 1 );
  448. if( ret == 1 )
  449. {
  450. Datei *capture = new Datei();
  451. capture->setDatei( "data/tmp/minigames/wb.mgc" );
  452. capture->erstellen();
  453. capture->open( Datei::Style::schreiben );
  454. int size = 0;
  455. k->getNachrichtEncrypted( (char*)&size, 4 );
  456. char *buffer = new char[ 2048 ];
  457. while( size > 0 )
  458. {
  459. int l = size > 2048 ? 2048 : size;
  460. k->getNachrichtEncrypted( buffer, l );
  461. capture->schreibe( buffer, l );
  462. size -= l;
  463. }
  464. delete[] buffer;
  465. capture->close();
  466. cs.unlock();
  467. return capture;
  468. }
  469. err = "Unbekannter Fehler";
  470. cs.unlock();
  471. return 0;
  472. }
  473. if( ret == 3 )
  474. {
  475. char l = 0;
  476. k->getNachrichtEncrypted( &l, 1 );
  477. char *fehler = new char[ l + 1 ];
  478. fehler[ l ] = 0;
  479. k->getNachrichtEncrypted( fehler, l );
  480. err = fehler;
  481. delete[] fehler;
  482. cs.unlock();
  483. return 0;
  484. }
  485. err = "Unbekannter Fehler";
  486. cs.unlock();
  487. return 0;
  488. }
  489. // Erhält die Verbindung aufrecht
  490. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  491. // Sollte während einer bestehenden Verbindung etwa einmal alle 60 Sekunden aufgerufen werden, da sonst der Router die Verbindung automatisch trennt
  492. bool MinigameClient::keepAlive()
  493. {
  494. char res = 0;
  495. if( !cs.tryLock() )
  496. return 1;
  497. if( !k )
  498. {
  499. err = "Der Client ist nicht verbunden.";
  500. cs.unlock();
  501. return 0;
  502. }
  503. bool ok = k->sendeEncrypted( "\x5", 1 );
  504. ok &= k->getNachrichtEncrypted( &res, 1 );
  505. cs.unlock();
  506. if( res != 1 || !ok )
  507. trenne( 0 );
  508. return res == 1;
  509. }
  510. // Trennt die Verbindung zum Server
  511. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  512. // Sollte erst nach einem erfolgreichen Aufruf von verbinde aufgerufen werden
  513. bool MinigameClient::trenne( bool abmelden )
  514. {
  515. cs.lock();
  516. verbinde();
  517. if( !k )
  518. {
  519. cs.unlock();
  520. return 1;
  521. }
  522. if( abmelden )
  523. {
  524. k->sendeEncrypted( "\4", 1 );
  525. char ret = 0;
  526. k->getNachrichtEncrypted( &ret, 1 );
  527. if( ret == 3 )
  528. { // error
  529. k->getNachrichtEncrypted( &ret, 1 );
  530. char *msg = new char[ ret + 1 ];
  531. msg[ ret ] = 0;
  532. if( ret )
  533. k->getNachrichtEncrypted( msg, ret );
  534. err = "error while unregister Client Minigame Server returned: ";
  535. err += msg;
  536. delete[] msg;
  537. }
  538. }
  539. k->sendeEncrypted( "\3", 1 );
  540. char ret = 0;
  541. k->getNachrichtEncrypted( &ret, 1 );
  542. if( ret == 3 )
  543. { // error
  544. k->getNachrichtEncrypted( &ret, 1 );
  545. char *msg = new char[ ret + 1 ];
  546. msg[ ret ] = 0;
  547. if( ret )
  548. k->getNachrichtEncrypted( msg, ret );
  549. err = "error while trenne Minigame Server returned: ";
  550. err += msg;
  551. delete[] msg;
  552. }
  553. k->trenne();
  554. k = k->release();
  555. cs.unlock();
  556. return 1;
  557. }
  558. // Gibt 1 zurück, falls der Client verbunden ist, 0 sonst
  559. bool MinigameClient::istVerbunden() const
  560. {
  561. return k != 0;
  562. }
  563. // gibt den Letzten Fehlertext zuück
  564. // sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist
  565. char *MinigameClient::getLetzterFehler() const
  566. {
  567. return err;
  568. }
  569. // Erhöht den Reference Counter um 1 un gibt this zurück
  570. MinigameServerClient *MinigameClient::getThis()
  571. {
  572. ref++;
  573. return this;
  574. }
  575. // Verringert den Reference Counter um 1 und gibt 0 zurück.
  576. // Falls der Reference Counter nach dem Aufruf auf 0 ist löscht sich das Objekt selbst
  577. MinigameServerClient *MinigameClient::release()
  578. {
  579. if( !--ref )
  580. delete this;
  581. return 0;
  582. }