MinigameClient.cpp 14 KB

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