SpielClient.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. #include "SpielClient.h"
  2. #include <Klient.h>
  3. #include "Keys.h"
  4. using namespace KSGClient;
  5. // Inhalt der SpielClient Klasse
  6. // Konstruktor
  7. SpielClient::SpielClient(int klientId, unsigned short port, const char* ip, const char* key, unsigned char keyLen)
  8. : ReferenceCounter()
  9. {
  10. this->ip = ip;
  11. this->port = port;
  12. cId = klientId;
  13. senden = 0;
  14. empfangen = 0;
  15. this->key = new char[keyLen];
  16. memcpy(this->key, key, keyLen);
  17. this->keyLen = keyLen;
  18. }
  19. // Destruktor
  20. SpielClient::~SpielClient()
  21. {
  22. trenne();
  23. delete[] key;
  24. }
  25. // verbindet sich mit dem zugewiesenen Karten Server
  26. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  27. bool SpielClient::verbinde()
  28. {
  29. cs.lock();
  30. if (senden)
  31. {
  32. cs.unlock();
  33. return 1;
  34. }
  35. if (!senden)
  36. senden = new Network::Klient();
  37. int keyLen = 0;
  38. char* key = 0;
  39. Keys::getServerKey(&key, keyLen, Keys::SPIEL, Keys::SENDEN);
  40. senden->setSendeKey(key, keyLen);
  41. delete[] key;
  42. Keys::getServerKey(&key, keyLen, Keys::SPIEL, Keys::EMPFANGEN);
  43. senden->setEmpfangKey(key, keyLen);
  44. delete[] key;
  45. if (senden->verbinde(port, ip))
  46. {
  47. if (senden->sendeEncrypted("\1", 1))
  48. {
  49. char serverReturn = 0;
  50. senden->sendeEncrypted((char*)&cId, 4);
  51. char ret = 0;
  52. senden->getNachrichtEncrypted(&ret, 1);
  53. if (ret != 1)
  54. {
  55. if (ret == 3)
  56. {
  57. char byte = 0;
  58. senden->getNachrichtEncrypted(&byte, 1);
  59. char* f = new char[byte + 1];
  60. f[byte] = 0;
  61. senden->getNachrichtEncrypted(f, byte);
  62. err = f;
  63. delete[]f;
  64. }
  65. senden->sendeEncrypted("\3", 1);
  66. senden->getNachrichtEncrypted(&serverReturn, 1);
  67. senden->trenne();
  68. senden = (Network::Klient*)senden->release();
  69. err = "Server akzeptiert den Klient nicht.";
  70. cs.unlock();
  71. return 0;
  72. }
  73. senden->setSendeKey(this->key, this->keyLen);
  74. senden->setEmpfangKey(this->key, this->keyLen);
  75. if (!empfangen)
  76. empfangen = new Network::Klient();
  77. int keyLen = 0;
  78. char* key = 0;
  79. Keys::getServerKey(&key, keyLen, Keys::SPIEL, Keys::SENDEN);
  80. empfangen->setSendeKey(key, keyLen);
  81. delete[] key;
  82. Keys::getServerKey(&key, keyLen, Keys::SPIEL, Keys::EMPFANGEN);
  83. empfangen->setEmpfangKey(key, keyLen);
  84. delete[] key;
  85. if (empfangen->verbinde(senden->getServerPort(), senden->getServerIp()))
  86. {
  87. empfangen->sendeEncrypted("\1", 1);
  88. empfangen->sendeEncrypted((char*)&cId, 4);
  89. char res = 0;
  90. empfangen->getNachrichtEncrypted(&res, 1);
  91. if (res == 3)
  92. {
  93. char län = 0;
  94. empfangen->getNachrichtEncrypted(&län, 1);
  95. char* nachricht = new char[län + 1];
  96. nachricht[län] = 0;
  97. empfangen->getNachrichtEncrypted(nachricht, län);
  98. err = nachricht;
  99. delete[] nachricht;
  100. }
  101. if (res == 1)
  102. {
  103. empfangen->setSendeKey(this->key, this->keyLen);
  104. empfangen->setEmpfangKey(this->key, this->keyLen);
  105. }
  106. else if (res != 0)
  107. {
  108. err = "Fehler beim Verbinden mit dem Spiel Server.";
  109. senden->sendeEncrypted("\3", 1);
  110. char serverReturn = 0;
  111. senden->getNachrichtEncrypted(&serverReturn, 1);
  112. senden->trenne();
  113. senden = (Network::Klient*)senden->release();
  114. empfangen->trenne();
  115. empfangen = (Network::Klient*)empfangen->release();
  116. return 0;
  117. }
  118. cs.unlock();
  119. return 1;
  120. }
  121. else
  122. {
  123. empfangen = (Network::Klient*)empfangen->release();
  124. senden->sendeEncrypted("\3", 1);
  125. char serverReturn = 0;
  126. senden->getNachrichtEncrypted(&serverReturn, 1);
  127. senden->trenne();
  128. senden = (Network::Klient*)senden->release();
  129. err = "Der dir zugewiesene Spiel Server kann dir keine Nachrichten senden.";
  130. cs.unlock();
  131. return 0;
  132. }
  133. }
  134. else
  135. {
  136. senden->trenne();
  137. senden = (Network::Klient*)senden->release();
  138. err = "Der dir zugewiesene Spiel Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut.";
  139. cs.unlock();
  140. return 0;
  141. }
  142. }
  143. else
  144. {
  145. err = "Der dir zugewiesene Spiel Server antwortet nicht. Bitte versuche es Später erneut.";
  146. senden = (Network::Klient*)senden->release();
  147. cs.unlock();
  148. return 0;
  149. }
  150. err = "Unbekannter Fehler";
  151. cs.unlock();
  152. return 0;
  153. }
  154. // Betritt das Vorgeschlagene Spiel
  155. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  156. bool SpielClient::spielErstelltAnnehmen()
  157. {
  158. cs.lock();
  159. if (!senden)
  160. {
  161. err = "Der Client ist nicht verbunden.";
  162. cs.unlock();
  163. return 0;
  164. }
  165. char ret = 0;
  166. senden->sendeEncrypted("\4", 1);
  167. senden->getNachrichtEncrypted(&ret, 1);
  168. if (ret != 1)
  169. err = "Fehler beim annehmen des Spiels.";
  170. cs.unlock();
  171. return ret == 1;
  172. }
  173. // Lehnt das Vorgeschlagene Spiel ab
  174. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  175. bool SpielClient::spielErstelltAblehnen()
  176. {
  177. cs.lock();
  178. if (!senden)
  179. {
  180. err = "Der Client ist nicht verbunden.";
  181. cs.unlock();
  182. return 0;
  183. }
  184. char ret = 0;
  185. senden->sendeEncrypted("\5", 1);
  186. senden->getNachrichtEncrypted(&ret, 1);
  187. if (ret != 1)
  188. err = "Fehler beim ablehnen des Spiels.";
  189. cs.unlock();
  190. return ret == 1;
  191. }
  192. // Wechselt zu einem bestimmten Team
  193. // team: Die Id des teams
  194. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  195. bool SpielClient::spielErstelltTeamWechseln(int team)
  196. {
  197. cs.lock();
  198. if (!senden)
  199. {
  200. err = "Der Client ist nicht verbunden.";
  201. cs.unlock();
  202. return 0;
  203. }
  204. char ret = 0;
  205. senden->sendeEncrypted("\6", 1);
  206. senden->getNachrichtEncrypted(&ret, 1);
  207. if (!ret)
  208. {
  209. err = "Fehler beim wechseln des Teams.";
  210. cs.unlock();
  211. return 0;
  212. }
  213. senden->sendeEncrypted((char*)&team, 4);
  214. senden->getNachrichtEncrypted(&ret, 1);
  215. if (ret != 1)
  216. err = "Fehler beim wechseln des Teams.";
  217. cs.unlock();
  218. return ret == 1;
  219. }
  220. // Bestätigt die Teamauswahl so dass das Spiel früher beginnen kann
  221. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  222. bool SpielClient::spielErstelltTeamFertig()
  223. {
  224. cs.lock();
  225. if (!senden)
  226. {
  227. err = "Der Client ist nicht verbunden.";
  228. cs.unlock();
  229. return 0;
  230. }
  231. char ret = 0;
  232. senden->sendeEncrypted("\xE", 1);
  233. senden->getNachrichtEncrypted(&ret, 1);
  234. if (ret != 1)
  235. err = "Fehler beim setzen der Bereitschaft.";
  236. cs.unlock();
  237. return ret == 1;
  238. }
  239. // sendet eine Chat Nachricht an die mitglieder des erstellten Spiels
  240. // nachricht: Die Nachricht
  241. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  242. bool SpielClient::spielErstelltChatNachricht(const char* nachricht)
  243. {
  244. char län = textLength(nachricht);
  245. if (!län)
  246. return 1;
  247. cs.lock();
  248. if (!senden)
  249. {
  250. err = "Der Client ist nicht verbunden.";
  251. cs.unlock();
  252. return 0;
  253. }
  254. char ret = 0;
  255. senden->sendeEncrypted("\7", 1);
  256. senden->getNachrichtEncrypted(&ret, 1);
  257. if (!ret)
  258. {
  259. err = "Fehler beim senden der Chat Nachricht.";
  260. cs.unlock();
  261. return 0;
  262. }
  263. senden->sendeEncrypted(&län, 1);
  264. senden->sendeEncrypted(nachricht, län);
  265. senden->getNachrichtEncrypted(&ret, 1);
  266. if (ret != 1)
  267. err = "Fehler beim senden der Chat Nachricht.";
  268. cs.unlock();
  269. return ret == 1;
  270. }
  271. // Teilt dem Server mit, dass der Client bereit ist das Spiel zu laden
  272. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  273. bool SpielClient::bereitZumLaden()
  274. {
  275. cs.lock();
  276. if (!senden)
  277. {
  278. err = "Der Client ist nicht verbunden.";
  279. cs.unlock();
  280. return 0;
  281. }
  282. char ret = 0;
  283. senden->sendeEncrypted("\x9", 1);
  284. senden->getNachrichtEncrypted(&ret, 1);
  285. if (ret != 1)
  286. err = "Fehler beim setzen der Bereitschaft.";
  287. cs.unlock();
  288. return ret == 1;
  289. }
  290. // Teilt dem Server mit, zu wie viel Prozent der Client das Spiel geladen hat
  291. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  292. bool SpielClient::setLadenProzent(int prozent)
  293. {
  294. cs.lock();
  295. if (!senden)
  296. {
  297. err = "Der Client ist nicht verbunden.";
  298. cs.unlock();
  299. return 0;
  300. }
  301. char ret = 0;
  302. senden->sendeEncrypted("\xC", 1);
  303. senden->getNachrichtEncrypted(&ret, 1);
  304. if (ret)
  305. {
  306. senden->sendeEncrypted((char*)&prozent, 4);
  307. senden->getNachrichtEncrypted(&ret, 1);
  308. }
  309. if (ret != 1)
  310. err = "Fehler beim setzen des Fortschritts.";
  311. cs.unlock();
  312. return ret == 1;
  313. }
  314. // Teilt dem Server mit, dass das Spiel fertig geladen wurde
  315. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  316. bool SpielClient::bereitZumSpiel()
  317. {
  318. cs.lock();
  319. if (!senden)
  320. {
  321. err = "Der Client ist nicht verbunden.";
  322. cs.unlock();
  323. return 0;
  324. }
  325. char ret = 0;
  326. senden->sendeEncrypted("\xA", 1);
  327. senden->getNachrichtEncrypted(&ret, 1);
  328. if (ret != 1)
  329. err = "Fehler beim setzen der Bereitschaft.";
  330. cs.unlock();
  331. return ret == 1;
  332. }
  333. // Sendet während des Spiels eine Nachricht an den Server
  334. // län: Die Länge der Nachricht
  335. // bytes: Ein Zeiger auf die Nachricht
  336. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  337. bool SpielClient::spielNachricht(short län, const char* bytes)
  338. {
  339. cs.lock();
  340. if (!senden)
  341. {
  342. err = "Der Client ist nicht verbunden.";
  343. cs.unlock();
  344. return 0;
  345. }
  346. senden->sendeEncrypted("\xB", 1);
  347. senden->sende((char*)&län, 2);
  348. senden->sende(bytes, län);
  349. cs.unlock();
  350. return 1;
  351. }
  352. // Sendet während der Statistik eine Nachricht an den Server
  353. // län: Die Länge der Nachricht
  354. // bytes: Ein Zeiger auf die Nachricht
  355. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  356. bool SpielClient::statistikNachricht(short län, const char* bytes)
  357. {
  358. cs.lock();
  359. if (!senden)
  360. {
  361. err = "Der Client ist nicht verbunden.";
  362. cs.unlock();
  363. return 0;
  364. }
  365. char ret = 0;
  366. senden->sendeEncrypted("\xD", 1);
  367. senden->getNachrichtEncrypted(&ret, 1);
  368. if (ret)
  369. {
  370. senden->sendeEncrypted((char*)&län, 2);
  371. senden->sendeEncrypted(bytes, län);
  372. senden->getNachrichtEncrypted(&ret, 1);
  373. }
  374. if (ret != 1)
  375. err = "Fehler beim setzen der Statistik Nachricht.";
  376. cs.unlock();
  377. return ret == 1;
  378. }
  379. // Wartet auf eine Nachricht vom Spiel Server.
  380. // Gibt bei Erfolg 1 zurück, 0 sonnst
  381. // nachricht: Eine Referenz auf die Struktur, in der die Nachricht gespeichert werden soll
  382. bool SpielClient::getNextMessage(SpielServerNachricht& nachricht)
  383. {
  384. do
  385. {
  386. if (!empfangen->getNachrichtEncrypted(&nachricht.type, 1))
  387. {
  388. err = "Es ist ein Fehler beim Empfangen aufgetreten";
  389. return 0;
  390. }
  391. switch (nachricht.type)
  392. {
  393. case 0: // verbindung getrennt
  394. trenne();
  395. break;
  396. case 1: // verbleibende Zeit
  397. empfangen->getNachrichtEncrypted(&nachricht.sekunden, 1);
  398. break;
  399. case 2: // SpielErstellt abbruch
  400. if (1)
  401. {
  402. char län = 0;
  403. empfangen->getNachrichtEncrypted(&län, 1);
  404. char* grund = new char[län + 1];
  405. grund[län] = 0;
  406. empfangen->getNachrichtEncrypted(grund, län);
  407. nachricht.message = grund;
  408. delete[] grund;
  409. }
  410. break;
  411. case 3: // Fehler
  412. if (1)
  413. {
  414. unsigned char länge = 0;
  415. empfangen->getNachrichtEncrypted((char*)&länge, 1);
  416. char* txt = new char[länge + 1];
  417. txt[länge] = 0;
  418. empfangen->getNachrichtEncrypted(txt, länge);
  419. nachricht.message = txt;
  420. delete[]txt;
  421. }
  422. break;
  423. case 4: // zurück in Warteschlange
  424. empfangen->getNachrichtEncrypted(&nachricht.stunden, 1);
  425. empfangen->getNachrichtEncrypted(&nachricht.minuten, 1);
  426. empfangen->getNachrichtEncrypted(&nachricht.sekunden, 1);
  427. break;
  428. case 6: // SpielErstellt Initialisierung
  429. empfangen->getNachrichtEncrypted((char*)&nachricht.sts->spielerAnzahl, 4);
  430. empfangen->getNachrichtEncrypted((char*)&nachricht.sts->teamAnzahl, 4);
  431. for (int i = 0; i < nachricht.sts->spielerAnzahl; i++)
  432. {
  433. int farbe = 0;
  434. empfangen->getNachrichtEncrypted((char*)&farbe, 4);
  435. nachricht.sts->spielerFarbe->set(farbe, i);
  436. }
  437. for (int i = 0; i < nachricht.sts->teamAnzahl; i++)
  438. {
  439. int farbe = 0;
  440. empfangen->getNachrichtEncrypted((char*)&farbe, 4);
  441. nachricht.sts->teamFarbe->set(farbe, i);
  442. }
  443. for (int i = 0; i < nachricht.sts->teamAnzahl; i++)
  444. {
  445. char län = 0;
  446. empfangen->getNachrichtEncrypted(&län, 1);
  447. char* name = new char[län + 1];
  448. name[län] = 0;
  449. if (län)
  450. empfangen->getNachrichtEncrypted(name, län);
  451. Text* tmp = new Text(name);
  452. delete[] name;
  453. nachricht.sts->teamName->set(tmp, i);
  454. }
  455. for (int i = 0; i < nachricht.sts->teamAnzahl; i++)
  456. {
  457. int größe = 0;
  458. empfangen->getNachrichtEncrypted((char*)&größe, 4);
  459. nachricht.sts->teamSize->set(größe, i);
  460. }
  461. break;
  462. case 7: // SpielErstellt Spieler hinzugefügt
  463. empfangen->getNachrichtEncrypted((char*)&nachricht.accountId, 4);
  464. break;
  465. case 8: // SpielErstellt Spieler entfernt
  466. empfangen->getNachrichtEncrypted((char*)&nachricht.accountId, 4);
  467. break;
  468. case 9: // SpielErstellt Spieler wechselt Team
  469. empfangen->getNachrichtEncrypted((char*)&nachricht.accountId, 4);
  470. empfangen->getNachrichtEncrypted((char*)&nachricht.spielerNummer, 4);
  471. break;
  472. case 0xA: // SpielErstellt Chat Nachricht
  473. if (1)
  474. {
  475. char län = 0;
  476. empfangen->getNachrichtEncrypted(&län, 1);
  477. char* txt = new char[län + 1];
  478. txt[län] = 0;
  479. if (län)
  480. empfangen->getNachrichtEncrypted(txt, län);
  481. nachricht.message = txt;
  482. delete[] txt;
  483. }
  484. break;
  485. case 0xB: // Spiel gefunden
  486. empfangen->getNachrichtEncrypted((char*)&nachricht.karteId, 4);
  487. break;
  488. case 0xD: // Spiel Laden Spieler hinzufügen
  489. empfangen->getNachrichtEncrypted((char*)&nachricht.accountId, 4);
  490. empfangen->getNachrichtEncrypted((char*)&nachricht.spielerNummer, 4);
  491. break;
  492. case 0xE: // Spiel Laden Spieler Prozent
  493. empfangen->getNachrichtEncrypted((char*)&nachricht.accountId, 4);
  494. empfangen->getNachrichtEncrypted((char*)&nachricht.prozent, 4);
  495. break;
  496. case 0xF: // Spiel Laden Spieler Ping
  497. empfangen->getNachrichtEncrypted((char*)&nachricht.accountId, 4);
  498. empfangen->getNachrichtEncrypted((char*)&nachricht.ping, 4);
  499. break;
  500. case 0x10: // ping
  501. empfangen->sendeEncrypted("\1", 1);
  502. break;
  503. case 0x12: // Spiel Nachricht
  504. empfangen->getNachricht((char*)&nachricht.län, 2);
  505. nachricht.data = new char[nachricht.län];
  506. empfangen->getNachricht(nachricht.data, nachricht.län);
  507. break;
  508. case 0x13: // Statistik Nachricht
  509. empfangen->getNachrichtEncrypted((char*)&nachricht.län, 2);
  510. nachricht.data = new char[nachricht.län];
  511. empfangen->getNachrichtEncrypted(nachricht.data, nachricht.län);
  512. break;
  513. case 0x14: // ping
  514. empfangen->sendeEncrypted("\1", 1);
  515. break;
  516. }
  517. } while (nachricht.type == 0x10 || nachricht.type == 0x14);
  518. return 1;
  519. }
  520. // Erhält die Verbindung aufrecht
  521. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  522. // Sollte während einer bestehenden Verbindung etwa einmal alle 60 Sekunden aufgerufen werden, da sonst der Router die Verbindung automatisch trennt
  523. bool SpielClient::keepAlive()
  524. {
  525. if (!senden)
  526. return 0;
  527. char res = 0;
  528. if (!cs.tryLock())
  529. return 1;
  530. bool ok = senden->sendeEncrypted("\xF", 1);
  531. ok &= senden->getNachrichtEncrypted(&res, 1);
  532. cs.unlock();
  533. if (res != 1 || !ok)
  534. {
  535. err = "Die Verbindung zum Spiel Server ist abgebrochen.";
  536. trenne();
  537. return 0;
  538. }
  539. return res == 1;
  540. }
  541. // Trennt die Verbindung zum Server
  542. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  543. // Sollte erst nach einem erfolgreichen Aufruf von verbinde aufgerufen werden
  544. bool SpielClient::trenne()
  545. {
  546. cs.lock();
  547. if (!senden)
  548. {
  549. cs.unlock();
  550. return 1;
  551. }
  552. senden->sendeEncrypted("\3", 1);
  553. char serverReturn = 0;
  554. senden->getNachrichtEncrypted(&serverReturn, 1);
  555. senden->trenne();
  556. senden = (Network::Klient*)senden->release();
  557. empfangen->trenne();
  558. empfangen = (Network::Klient*)empfangen->release();
  559. cs.unlock();
  560. return 1;
  561. }
  562. // Gibt 1 zurück, falls der Client verbunden ist, 0 sonst
  563. bool SpielClient::istVerbunden() const
  564. {
  565. return senden != 0;
  566. }
  567. // gibt den Letzten Fehlertext zuück
  568. // sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist
  569. const char* SpielClient::getLetzterFehler() const
  570. {
  571. return err;
  572. }