SpielClient.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  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, char *ip, char *key, unsigned char keyLen )
  8. {
  9. ref = 1;
  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 = 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 = senden->release();
  114. empfangen->trenne();
  115. empfangen = empfangen->release();
  116. return 0;
  117. }
  118. cs.unlock();
  119. return 1;
  120. }
  121. else
  122. {
  123. empfangen = empfangen->release();
  124. senden->sendeEncrypted( "\3", 1 );
  125. char serverReturn = 0;
  126. senden->getNachrichtEncrypted( &serverReturn, 1 );
  127. senden->trenne();
  128. senden = 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 = 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 = 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( 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, 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, 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 = senden->release();
  557. empfangen->trenne();
  558. empfangen = 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. char *SpielClient::getLetzterFehler() const
  570. {
  571. return err;
  572. }
  573. // Erhöht den Reference Counter um 1 un gibt this zurück
  574. SpielServerClient *SpielClient::getThis()
  575. {
  576. ref++;
  577. return this;
  578. }
  579. // Verringert den Reference Counter um 1 und gibt 0 zurück.
  580. // Falls der Reference Counter nach dem Aufruf auf 0 ist löscht sich das Objekt selbst
  581. SpielServerClient *SpielClient::release()
  582. {
  583. if( !--ref )
  584. delete this;
  585. return 0;
  586. }