MinigameClient.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  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. // Ermittelt die liste mit allen Optionen zu einem Minigame zurück, zu denen es Welt beste Scores gibt
  87. // mName: Der Name des Minigames
  88. // zOptionList: Enthält nach erfolgreichem Aufruf eine Liste mit Optionen
  89. // Gibt die Anzahl der Optionen zurück
  90. int MinigameClient::getMinigameOptionList( char *mName, Framework::RCArray< Framework::Text > *zOptionList )
  91. {
  92. cs.lock();
  93. if( !k )
  94. {
  95. if( !verbinde() )
  96. {
  97. err = "Der Client ist nicht verbunden.";
  98. cs.unlock();
  99. return 0;
  100. }
  101. }
  102. k->sendeEncrypted( "\x6", 1 );
  103. char ret = 0;
  104. k->getNachrichtEncrypted( &ret, 1 );
  105. if( ret == 1 )
  106. {
  107. char l = (char)textLength( mName );
  108. k->sendeEncrypted( &l, 1 );
  109. k->sendeEncrypted( mName, l );
  110. int anz = 0;
  111. k->getNachrichtEncrypted( (char*)&anz, 4 );
  112. for( int i = 0; i < anz; i++ )
  113. {
  114. k->getNachrichtEncrypted( &l, 1 );
  115. char *option = new char[ l + 1 ];
  116. option[ l ] = 0;
  117. k->getNachrichtEncrypted( option, l );
  118. zOptionList->add( new Text( option ) );
  119. delete[] option;
  120. }
  121. cs.unlock();
  122. return anz;
  123. }
  124. if( ret == 3 )
  125. {
  126. char l = 0;
  127. k->getNachrichtEncrypted( &l, 1 );
  128. char *fehler = new char[ l + 1 ];
  129. fehler[ l ] = 0;
  130. k->getNachrichtEncrypted( fehler, l );
  131. err = fehler;
  132. delete[] fehler;
  133. cs.unlock();
  134. return 0;
  135. }
  136. err = "Unbekannter Fehler";
  137. cs.unlock();
  138. return 0;
  139. }
  140. // Ermittelt eine Liste mit den Weltbesten Scores zurück
  141. // mName: Der Name des Minigames
  142. // zScore: Enthält nach erfolgreichem Aufruf eine Liste mit Scores
  143. // zPlayerList: Enthält nach erfolgreichem Aufruf eine Liste mit angezeigten Account Namen, die die Scores erreicht haben.
  144. // zOptionList: Enthält nach erfolgreichem Aufruf eine Liste mit Optionen, die beim erreichen der Scores aktiv waren.
  145. // Gibt die Anzahl der Bestscores zurück
  146. int MinigameClient::getMinigameBestscoreList( char *mName, Framework::Array< int > *zScore, Framework::RCArray< Framework::Text > *zPlayerList, Framework::RCArray< Framework::Text > *zOptionList )
  147. {
  148. cs.lock();
  149. if( !k )
  150. {
  151. if( !verbinde() )
  152. {
  153. err = "Der Client ist nicht verbunden.";
  154. cs.unlock();
  155. return 0;
  156. }
  157. }
  158. k->sendeEncrypted( "\x7", 1 );
  159. char ret = 0;
  160. k->getNachrichtEncrypted( &ret, 1 );
  161. if( ret == 1 )
  162. {
  163. char l = (char)textLength( mName );
  164. k->sendeEncrypted( &l, 1 );
  165. k->sendeEncrypted( mName, l );
  166. int anz = 0;
  167. k->getNachrichtEncrypted( (char*)&anz, 4 );
  168. for( int i = 0; i < anz; i++ )
  169. {
  170. int score = 0;
  171. k->getNachrichtEncrypted( (char*)&score, 4 );
  172. zScore->add( score );
  173. k->getNachrichtEncrypted( &l, 1 );
  174. char *player = new char[ l + 1 ];
  175. player[ l ] = 0;
  176. k->getNachrichtEncrypted( player, l );
  177. zPlayerList->add( new Text( player ) );
  178. delete[] player;
  179. k->getNachrichtEncrypted( &l, 1 );
  180. char *option = new char[ l + 1 ];
  181. option[ l ] = 0;
  182. k->getNachrichtEncrypted( option, l );
  183. zOptionList->add( new Text( option ) );
  184. delete[] option;
  185. }
  186. cs.unlock();
  187. return anz;
  188. }
  189. if( ret == 3 )
  190. {
  191. char l = 0;
  192. k->getNachrichtEncrypted( &l, 1 );
  193. char *fehler = new char[ l + 1 ];
  194. fehler[ l ] = 0;
  195. k->getNachrichtEncrypted( fehler, l );
  196. err = fehler;
  197. delete[] fehler;
  198. cs.unlock();
  199. return 0;
  200. }
  201. err = "Unbekannter Fehler";
  202. cs.unlock();
  203. return 0;
  204. }
  205. // Gibt den Welt bestscore zu einem Bestimmten Minigame mit bestimmten Optionen zurück.
  206. // mName: Der Name des Minigames
  207. // oName: Die Optionen
  208. // zPlayer: Enthält nach erfolgreichem Aufruf den Angezeigten Namen des Accounts, der den Score erreicht hat
  209. int MinigameClient::getMinigameOptionBestscore( char *mName, char *oName, Framework::Text *zPlayer )
  210. {
  211. cs.lock();
  212. if( !k )
  213. {
  214. if( !verbinde() )
  215. {
  216. err = "Der Client ist nicht verbunden.";
  217. cs.unlock();
  218. return 0;
  219. }
  220. }
  221. k->sendeEncrypted( "\x8", 1 );
  222. char ret = 0;
  223. k->getNachrichtEncrypted( &ret, 1 );
  224. if( ret == 1 )
  225. {
  226. char l = (char)textLength( mName );
  227. k->sendeEncrypted( &l, 1 );
  228. k->sendeEncrypted( mName, l );
  229. l = (char)textLength( oName );
  230. k->sendeEncrypted( &l, 1 );
  231. k->sendeEncrypted( oName, l );
  232. int score = 0;
  233. k->getNachrichtEncrypted( (char*)&score, 4 );
  234. k->getNachrichtEncrypted( &l, 1 );
  235. char *player = new char[ l + 1 ];
  236. player[ l ] = 0;
  237. k->getNachrichtEncrypted( player, l );
  238. zPlayer->setText( player );
  239. delete[] player;
  240. cs.unlock();
  241. return score;
  242. }
  243. if( ret == 3 )
  244. {
  245. char l = 0;
  246. k->getNachrichtEncrypted( &l, 1 );
  247. char *fehler = new char[ l + 1 ];
  248. fehler[ l ] = 0;
  249. k->getNachrichtEncrypted( fehler, l );
  250. err = fehler;
  251. delete[] fehler;
  252. cs.unlock();
  253. return 0;
  254. }
  255. err = "Unbekannter Fehler";
  256. cs.unlock();
  257. return 0;
  258. }
  259. // Meldet die Beendigung eines Minigames
  260. // mName: Der Name des Minigames
  261. // oName: Die Optionen mit denen gespielt wurde
  262. // score: Der Erreichte Score
  263. // zCapture: Ein Zeiger auf eine Datei mit der Spielaufzeichnung
  264. // Gibt 0 zurück wenn eines Fehler aufgetreten ist, 1 wenn der Forgang erfolgreich war
  265. bool MinigameClient::reportEndOfGame( char *mName, char *oName, int score, Framework::Datei *zCapture )
  266. {
  267. cs.lock();
  268. if( !k )
  269. {
  270. if( !verbinde() )
  271. {
  272. err = "Der Client ist nicht verbunden.";
  273. cs.unlock();
  274. return 0;
  275. }
  276. }
  277. k->sendeEncrypted( "\x9", 1 );
  278. char ret = 0;
  279. k->getNachrichtEncrypted( &ret, 1 );
  280. if( ret == 1 )
  281. {
  282. char l = (char)textLength( mName );
  283. k->sendeEncrypted( &l, 1 );
  284. k->sendeEncrypted( mName, l );
  285. l = (char)textLength( oName );
  286. k->sendeEncrypted( &l, 1 );
  287. k->sendeEncrypted( oName, l );
  288. k->sendeEncrypted( (char*)&score, 4 );
  289. k->getNachrichtEncrypted( &ret, 1 );
  290. if( ret == 1 )
  291. {
  292. int size = (int)zCapture->getSize();
  293. if( !zCapture->istOffen() )
  294. zCapture->open( Datei::Style::lesen );
  295. k->sendeEncrypted( (char*)&size, 4 );
  296. char *buffer = new char[ 2048 ];
  297. while( size > 0 )
  298. {
  299. int l = size > 2048 ? 2048 : size;
  300. zCapture->lese( buffer, l );
  301. k->sendeEncrypted( buffer, l );
  302. size -= l;
  303. }
  304. delete[] buffer;
  305. zCapture->close();
  306. cs.unlock();
  307. return 1;
  308. }
  309. else if( ret == 0 )
  310. {
  311. cs.unlock();
  312. return 1;
  313. }
  314. }
  315. if( ret == 3 )
  316. {
  317. char l = 0;
  318. k->getNachrichtEncrypted( &l, 1 );
  319. char *fehler = new char[ l + 1 ];
  320. fehler[ l ] = 0;
  321. k->getNachrichtEncrypted( fehler, l );
  322. err = fehler;
  323. delete[] fehler;
  324. cs.unlock();
  325. return 0;
  326. }
  327. err = "Unbekannter Fehler";
  328. cs.unlock();
  329. return 0;
  330. }
  331. // Lädt ein Game Capture herunter und speichert sie unter data/tmp/minigames/wb.mgc
  332. // mName: Der Name des Minigames
  333. // oName: Die Optionen
  334. // Gibt die Datei mit dem Capture zurück
  335. Framework::Datei *MinigameClient::downloadGameCapture( char *mName, char *oName )
  336. {
  337. cs.lock();
  338. if( !k )
  339. {
  340. if( !verbinde() )
  341. {
  342. err = "Der Client ist nicht verbunden.";
  343. cs.unlock();
  344. return 0;
  345. }
  346. }
  347. k->sendeEncrypted( "\xA", 1 );
  348. char ret = 0;
  349. k->getNachrichtEncrypted( &ret, 1 );
  350. if( ret == 1 )
  351. {
  352. char l = (char)textLength( mName );
  353. k->sendeEncrypted( &l, 1 );
  354. k->sendeEncrypted( mName, l );
  355. l = (char)textLength( oName );
  356. k->sendeEncrypted( &l, 1 );
  357. k->sendeEncrypted( oName, l );
  358. k->getNachrichtEncrypted( &ret, 1 );
  359. if( ret == 1 )
  360. {
  361. Datei *capture = new Datei();
  362. capture->setDatei( "data/tmp/minigames/wb.mgc" );
  363. capture->erstellen();
  364. capture->open( Datei::Style::schreiben );
  365. int size = 0;
  366. k->getNachrichtEncrypted( (char*)&size, 4 );
  367. char *buffer = new char[ 2048 ];
  368. while( size > 0 )
  369. {
  370. int l = size > 2048 ? 2048 : size;
  371. k->getNachrichtEncrypted( buffer, l );
  372. capture->schreibe( buffer, l );
  373. size -= l;
  374. }
  375. delete[] buffer;
  376. capture->close();
  377. cs.unlock();
  378. return capture;
  379. }
  380. err = "Unbekannter Fehler";
  381. cs.unlock();
  382. return 0;
  383. }
  384. if( ret == 3 )
  385. {
  386. char l = 0;
  387. k->getNachrichtEncrypted( &l, 1 );
  388. char *fehler = new char[ l + 1 ];
  389. fehler[ l ] = 0;
  390. k->getNachrichtEncrypted( fehler, l );
  391. err = fehler;
  392. delete[] fehler;
  393. cs.unlock();
  394. return 0;
  395. }
  396. err = "Unbekannter Fehler";
  397. cs.unlock();
  398. return 0;
  399. }
  400. // Erhält die Verbindung aufrecht
  401. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  402. // Sollte während einer bestehenden Verbindung etwa einmal alle 60 Sekunden aufgerufen werden, da sonst der Router die Verbindung automatisch trennt
  403. bool MinigameClient::keepAlive()
  404. {
  405. char res = 0;
  406. if( !cs.tryLock() )
  407. return 1;
  408. if( !k )
  409. {
  410. err = "Der Client ist nicht verbunden.";
  411. cs.unlock();
  412. return 0;
  413. }
  414. bool ok = k->sendeEncrypted( "\x5", 1 );
  415. ok &= k->getNachrichtEncrypted( &res, 1 );
  416. cs.unlock();
  417. if( res != 1 || !ok )
  418. trenne( 0 );
  419. return res == 1;
  420. }
  421. // Trennt die Verbindung zum Server
  422. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  423. // Sollte erst nach einem erfolgreichen Aufruf von verbinde aufgerufen werden
  424. bool MinigameClient::trenne( bool abmelden )
  425. {
  426. cs.lock();
  427. verbinde();
  428. if( !k )
  429. {
  430. cs.unlock();
  431. return 1;
  432. }
  433. if( abmelden )
  434. {
  435. k->sendeEncrypted( "\4", 1 );
  436. char ret = 0;
  437. k->getNachrichtEncrypted( &ret, 1 );
  438. if( ret == 3 )
  439. { // error
  440. k->getNachrichtEncrypted( &ret, 1 );
  441. char *msg = new char[ ret + 1 ];
  442. msg[ ret ] = 0;
  443. if( ret )
  444. k->getNachrichtEncrypted( msg, ret );
  445. err = "error while unregister Client Minigame Server returned: ";
  446. err += msg;
  447. delete[] msg;
  448. }
  449. }
  450. k->sendeEncrypted( "\3", 1 );
  451. char ret = 0;
  452. k->getNachrichtEncrypted( &ret, 1 );
  453. if( ret == 3 )
  454. { // error
  455. k->getNachrichtEncrypted( &ret, 1 );
  456. char *msg = new char[ ret + 1 ];
  457. msg[ ret ] = 0;
  458. if( ret )
  459. k->getNachrichtEncrypted( msg, ret );
  460. err = "error while trenne Minigame Server returned: ";
  461. err += msg;
  462. delete[] msg;
  463. }
  464. k->trenne();
  465. k = k->release();
  466. cs.unlock();
  467. return 1;
  468. }
  469. // Gibt 1 zurück, falls der Client verbunden ist, 0 sonst
  470. bool MinigameClient::istVerbunden() const
  471. {
  472. return k != 0;
  473. }
  474. // gibt den Letzten Fehlertext zuück
  475. // sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist
  476. char *MinigameClient::getLetzterFehler() const
  477. {
  478. return err;
  479. }
  480. // Erhöht den Reference Counter um 1 un gibt this zurück
  481. MinigameServerClient *MinigameClient::getThis()
  482. {
  483. ref++;
  484. return this;
  485. }
  486. // Verringert den Reference Counter um 1 und gibt 0 zurück.
  487. // Falls der Reference Counter nach dem Aufruf auf 0 ist löscht sich das Objekt selbst
  488. MinigameServerClient *MinigameClient::release()
  489. {
  490. if( !--ref )
  491. delete this;
  492. return 0;
  493. }