MinigameClient.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  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, const char* ip, const char* key, unsigned char keyLen)
  9. : ReferenceCounter()
  10. {
  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 = (Network::Klient*)k->release();
  72. cs.unlock();
  73. return 0;
  74. }
  75. }
  76. else
  77. {
  78. err = "network error while connecting to Minigame Server";
  79. k = (Network::Klient*)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(const 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(const 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(const char* mName, const 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(const char* mName, const 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(const char* mName, const 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 = (Network::Klient*)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. const char* MinigameClient::getLetzterFehler() const
  610. {
  611. return err;
  612. }