PatchClient.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. #include "PatchClient.h"
  2. #include <Klient.h>
  3. #include <KSGTDatei.h>
  4. #include "Keys.h"
  5. #include <Datei.h>
  6. #include <Zeit.h>
  7. #include <Fortschritt.h>
  8. using namespace KSGClient;
  9. // Inhalt der PatchClient Klasse
  10. // Konstruktor
  11. PatchClient::PatchClient(int klientId, unsigned short port, const char* ip, const char* key, unsigned char keyLen)
  12. : ReferenceCounter()
  13. {
  14. this->ip = ip;
  15. this->port = port;
  16. cId = klientId;
  17. k = 0;
  18. this->key = new char[keyLen];
  19. memcpy(this->key, key, keyLen);
  20. this->keyLen = keyLen;
  21. }
  22. // Destruktor
  23. PatchClient::~PatchClient()
  24. {
  25. trenne(1);
  26. delete[] key;
  27. }
  28. // verbindet ich mit dem Patch Server
  29. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  30. bool PatchClient::verbinde()
  31. {
  32. cs.lock();
  33. if (k)
  34. {
  35. cs.unlock();
  36. return 1;
  37. }
  38. k = new Network::Klient();
  39. int l = 0;
  40. char* key;
  41. Keys::getServerKey(&key, l, Keys::PATCH, Keys::SENDEN);
  42. k->setSendeKey(key, l);
  43. delete[] key;
  44. Keys::getServerKey(&key, l, Keys::PATCH, Keys::EMPFANGEN);
  45. k->setEmpfangKey(key, l);
  46. delete[] key;
  47. if (k->verbinde(port, ip))
  48. {
  49. k->sende("\0", 1); // Verschlüsselung Aktivieren
  50. if (k->sendeEncrypted("\1", 1))
  51. {
  52. k->sendeEncrypted((char*)&cId, 4);
  53. #ifdef _X64
  54. k->sendeEncrypted("\2", 1); // 64 Bit Client
  55. #else
  56. k->sendeEncrypted("\1", 1); // 32 Bit Client
  57. #endif
  58. char serverReturn = 0;
  59. k->getNachrichtEncrypted(&serverReturn, 1);
  60. if (serverReturn == 3)
  61. {
  62. char byte = 0;
  63. k->getNachrichtEncrypted(&byte, 1);
  64. char* f = new char[byte + 1];
  65. f[byte] = 0;
  66. k->getNachrichtEncrypted(f, byte);
  67. err = "error while identifying client Patch Server returned: ";
  68. err += f;
  69. delete[]f;
  70. trenne(0);
  71. cs.unlock();
  72. return 0;
  73. }
  74. k->setSendeKey(this->key, this->keyLen);
  75. k->setEmpfangKey(this->key, this->keyLen);
  76. }
  77. else
  78. {
  79. err = "network error while sending to Patch Server";
  80. k = (Network::Klient*)k->release();
  81. cs.unlock();
  82. return 0;
  83. }
  84. }
  85. else
  86. {
  87. err = "network error while connecting to Patch Server";
  88. k = (Network::Klient*)k->release();
  89. cs.unlock();
  90. return 0;
  91. }
  92. cs.unlock();
  93. return 1;
  94. }
  95. // Gibt eine Tabelle von Dateigruppen zurück.
  96. // Gibt bei misserfolg 0 zurück
  97. Framework::KSGTDatei* PatchClient::getDateiGruppenListe()
  98. {
  99. cs.lock();
  100. if (!k)
  101. {
  102. err = "Der Client ist nicht verbunden.";
  103. cs.unlock();
  104. return 0;
  105. }
  106. k->sendeEncrypted("\xC", 1);
  107. char ret = 0;
  108. k->getNachrichtEncrypted(&ret, 1);
  109. if (ret == 3)
  110. { // error
  111. k->getNachrichtEncrypted(&ret, 1);
  112. char* msg = new char[ret + 1];
  113. msg[ret] = 0;
  114. if (ret)
  115. k->getNachrichtEncrypted(msg, ret);
  116. err = msg;
  117. delete[] msg;
  118. cs.unlock();
  119. return 0;
  120. }
  121. Framework::KSGTDatei* dgtb = new Framework::KSGTDatei();
  122. int id = 0;
  123. k->getNachrichtEncrypted((char*)&id, 4);
  124. while (id)
  125. {
  126. RCArray< Text >* zeile = new RCArray< Text >();
  127. Text* idT = new Text();
  128. idT->append(id);
  129. zeile->set(idT, 0);
  130. int län = 0;
  131. k->getNachrichtEncrypted((char*)&län, 4);
  132. char* pfad = new char[län + 1];
  133. pfad[län] = 0;
  134. if (län)
  135. k->getNachrichtEncrypted(pfad, län);
  136. zeile->set(new Text(pfad), 1);
  137. delete[] pfad;
  138. int vs = 0;
  139. k->getNachrichtEncrypted((char*)&vs, 4);
  140. Text* vsT = new Text();
  141. vsT->append(vs);
  142. zeile->set(vsT, 2);
  143. dgtb->addZeile(3, zeile);
  144. zeile->release();
  145. k->getNachrichtEncrypted((char*)&id, 4);
  146. }
  147. k->sendeEncrypted("\1", 1);
  148. cs.unlock();
  149. return dgtb;
  150. }
  151. // Gibt eine Tabelle von Dateien zurück.
  152. // gruppe: Die Id der Dateigruppe, zu der die Dateien gehöhren sollen
  153. // Gibt bei misserfolg 0 zurück
  154. Framework::KSGTDatei* PatchClient::getDateiListe(int gruppe)
  155. {
  156. cs.lock();
  157. if (!k)
  158. {
  159. err = "Der Client ist nicht verbunden.";
  160. cs.unlock();
  161. return 0;
  162. }
  163. k->sendeEncrypted("\x9", 1);
  164. char ret = 0;
  165. k->getNachrichtEncrypted(&ret, 1);
  166. if (ret == 3)
  167. { // error
  168. k->getNachrichtEncrypted(&ret, 1);
  169. char* msg = new char[ret + 1];
  170. msg[ret] = 0;
  171. if (ret)
  172. k->getNachrichtEncrypted(msg, ret);
  173. err = msg;
  174. delete[] msg;
  175. cs.unlock();
  176. return 0;
  177. }
  178. k->sendeEncrypted((char*)&gruppe, 4);
  179. k->getNachrichtEncrypted(&ret, 1);
  180. if (ret == 3)
  181. { // error
  182. k->getNachrichtEncrypted(&ret, 1);
  183. char* msg = new char[ret + 1];
  184. msg[ret] = 0;
  185. if (ret)
  186. k->getNachrichtEncrypted(msg, ret);
  187. err = msg;
  188. delete[] msg;
  189. cs.unlock();
  190. return 0;
  191. }
  192. KSGTDatei* dtb = new KSGTDatei();
  193. int län = 0;
  194. k->getNachrichtEncrypted((char*)&län, 4);
  195. while (län)
  196. {
  197. RCArray< Text >* zeile = new RCArray< Text >();
  198. zeile->set(new Text("1"), 0);
  199. char* pfad = new char[län + 1];
  200. pfad[län] = 0;
  201. k->getNachrichtEncrypted(pfad, län);
  202. zeile->set(new Text(pfad), 1);
  203. delete[] pfad;
  204. int vs = 0;
  205. k->getNachrichtEncrypted((char*)&vs, 4);
  206. Text* vsT = new Text();
  207. vsT->append(vs);
  208. zeile->set(vsT, 2);
  209. dtb->addZeile(3, zeile);
  210. zeile->release();
  211. k->getNachrichtEncrypted((char*)&län, 4);
  212. }
  213. k->getNachrichtEncrypted((char*)&län, 4);
  214. while (län)
  215. {
  216. RCArray< Text >* zeile = new RCArray< Text >();
  217. zeile->set(new Text("0"), 0);
  218. char* pfad = new char[län + 1];
  219. pfad[län] = 0;
  220. k->getNachrichtEncrypted(pfad, län);
  221. zeile->set(new Text(pfad), 1);
  222. delete[] pfad;
  223. dtb->addZeile(2, zeile);
  224. zeile->release();
  225. k->getNachrichtEncrypted((char*)&län, 4);
  226. }
  227. cs.unlock();
  228. return dtb;
  229. }
  230. // Gibt die Größe einer Datei in bytes zurück
  231. // gruppe: Die Id der Dateigruppe der Datei
  232. // pfad: Der Pfad der Datei
  233. __int64 PatchClient::getDateiGröße(int gruppe, const char* pfad)
  234. {
  235. cs.lock();
  236. if (!k)
  237. {
  238. err = "Der Client ist nicht verbunden.";
  239. cs.unlock();
  240. return 0;
  241. }
  242. k->sendeEncrypted("\xA", 1);
  243. char ret = 0;
  244. k->getNachrichtEncrypted(&ret, 1);
  245. if (ret == 3)
  246. { // error
  247. k->getNachrichtEncrypted(&ret, 1);
  248. char* msg = new char[ret + 1];
  249. msg[ret] = 0;
  250. if (ret)
  251. k->getNachrichtEncrypted(msg, ret);
  252. err = msg;
  253. delete[] msg;
  254. cs.unlock();
  255. return 0;
  256. }
  257. k->sendeEncrypted((char*)&gruppe, 4);
  258. ret = 0;
  259. k->getNachrichtEncrypted(&ret, 1);
  260. if (ret == 3)
  261. { // error
  262. k->getNachrichtEncrypted(&ret, 1);
  263. char* msg = new char[ret + 1];
  264. msg[ret] = 0;
  265. if (ret)
  266. k->getNachrichtEncrypted(msg, ret);
  267. err = msg;
  268. delete[] msg;
  269. cs.unlock();
  270. return 0;
  271. }
  272. if (ret == 2)
  273. { // verweis auf anderen Server
  274. int p = 0;
  275. k->getNachrichtEncrypted((char*)&p, 4);
  276. port = (unsigned short)p;
  277. int län = 0;
  278. k->getNachrichtEncrypted((char*)&län, 4);
  279. char* ip = new char[län + 1];
  280. ip[län] = 0;
  281. k->getNachrichtEncrypted(ip, län);
  282. this->ip = ip;
  283. delete[]ip;
  284. if (!trenne(0))
  285. {
  286. err = "Fehler beim wechseln des Servers: Die Verbindung konnte nicht getrennt werden.";
  287. cs.unlock();
  288. return 0;
  289. }
  290. if (!verbinde())
  291. {
  292. err = "Fehler beim wechseln des Servers: Die Verbindung konnte nicht hergestellt werden.";
  293. cs.unlock();
  294. return 0;
  295. }
  296. cs.unlock();
  297. return getDateiGröße(gruppe, pfad);
  298. }
  299. int län = textLength(pfad);
  300. k->sendeEncrypted((char*)&län, 4);
  301. k->sendeEncrypted(pfad, län);
  302. __int64 größe = 0;
  303. k->getNachrichtEncrypted((char*)&größe, 8);
  304. cs.unlock();
  305. return größe;
  306. }
  307. // Lädt eine Datei herunter
  308. // gruppe: Die Dateigruppe der Datei
  309. // start: Der Index des bytes, bei dem der download begonnen werden soll (Enthält im Falle eines Abbruchs die Position, von welcher aus als nächstes heruntergeladen werden muss)
  310. // pfad: Der Pfad der Datei
  311. // zielPfad: Der Pfad, an den die Datei gespeichert werden soll
  312. // zFb: Ein Fortschrittsbalken, der automatisch aktualisiert wird
  313. // abbruch: Wenn diese Variable während des Vorgangs auf 1 gesetzt wird, so wird das Herunterladen abgebrochen.
  314. // maxbps: Die Anzahl der bytes pro Sekunde, die maximal übertragen werden sollen
  315. bool PatchClient::downloadDatei(int gruppe, __int64* start, const char* pfad, const char* zielPfad, Framework::FBalken* zFb, bool* abbruch, int maxbps)
  316. {
  317. cs.lock();
  318. if (!k)
  319. {
  320. err = "Der Client ist nicht verbunden.";
  321. cs.unlock();
  322. return 0;
  323. }
  324. Datei* zielD = new Datei();
  325. zielD->setDatei(zielPfad);
  326. if (!zielD->existiert())
  327. zielD->erstellen();
  328. bool ok = 0;
  329. if (!(*start)) // datei neu erstellen
  330. ok = zielD->open(Datei::Style::schreiben);
  331. else // datei weiterschreiben
  332. ok = zielD->open(Datei::Style::schreiben | Datei::Style::lesen);
  333. if (!ok)
  334. {
  335. zielD->release();
  336. err = "Die Datei konnte nicht zum schreiben geöffnet werden.";
  337. cs.unlock();
  338. return 0;
  339. }
  340. zielD->setSPosition(*start, 0);
  341. k->sendeEncrypted("\xB", 1);
  342. char ret = 0;
  343. k->getNachrichtEncrypted(&ret, 1);
  344. if (ret == 3)
  345. { // error
  346. k->getNachrichtEncrypted(&ret, 1);
  347. char* msg = new char[ret + 1];
  348. msg[ret] = 0;
  349. if (ret)
  350. k->getNachrichtEncrypted(msg, ret);
  351. err = msg;
  352. delete[] msg;
  353. zielD->close();
  354. zielD->release();
  355. cs.unlock();
  356. return 0;
  357. }
  358. k->sendeEncrypted((char*)&gruppe, 4);
  359. ret = 0;
  360. k->getNachrichtEncrypted(&ret, 1);
  361. if (ret == 3)
  362. { // error
  363. k->getNachrichtEncrypted(&ret, 1);
  364. char* msg = new char[ret + 1];
  365. msg[ret] = 0;
  366. if (ret)
  367. k->getNachrichtEncrypted(msg, ret);
  368. err = msg;
  369. delete[] msg;
  370. zielD->close();
  371. zielD->release();
  372. cs.unlock();
  373. return 0;
  374. }
  375. if (ret == 2)
  376. { // verweis auf anderen Server
  377. int p = 0;
  378. k->getNachrichtEncrypted((char*)&p, 4);
  379. port = (unsigned short)p;
  380. int län = 0;
  381. k->getNachrichtEncrypted((char*)&län, 4);
  382. char* ip = new char[län + 1];
  383. ip[län] = 0;
  384. k->getNachrichtEncrypted(ip, län);
  385. this->ip = ip;
  386. delete[] ip;
  387. if (!trenne(0))
  388. {
  389. zielD->close();
  390. zielD->release();
  391. err = "Fehler beim wechseln des Servers: Die Verbindung konnte nicht getrennt werden.";
  392. cs.unlock();
  393. return 0;
  394. }
  395. if (!verbinde())
  396. {
  397. zielD->close();
  398. zielD->release();
  399. err = "Fehler beim wechseln des Servers: Die Verbindung konnte nicht hergestellt werden.";
  400. cs.unlock();
  401. return 0;
  402. }
  403. zielD->close();
  404. zielD->release();
  405. cs.unlock();
  406. return downloadDatei(gruppe, start, pfad, zielPfad, zFb, abbruch, maxbps);
  407. }
  408. int län = textLength(pfad);
  409. k->sendeEncrypted((char*)&län, 4);
  410. k->sendeEncrypted(pfad, län);
  411. k->sendeEncrypted((char*)start, 8);
  412. char* bytes = new char[2048];
  413. unsigned short byteLän = 0;
  414. k->getNachricht((char*)&byteLän, 2);
  415. ZeitMesser* zMess = new ZeitMesser();
  416. zMess->messungStart();
  417. if (byteLän)
  418. {
  419. int bps = 0;
  420. double sec = 0;
  421. while (1)
  422. {
  423. k->getNachricht(bytes, byteLän);
  424. zielD->schreibe(bytes, byteLän);
  425. if (zFb)
  426. zFb->aktionPlus(byteLän);
  427. (*start) += byteLän;
  428. bps += byteLän;
  429. if (byteLän == 2048)
  430. {
  431. if ((*abbruch))
  432. {
  433. zielD->close();
  434. zielD->release();
  435. k->trenne();
  436. k = (Network::Klient*)k->release();
  437. delete[] bytes;
  438. zMess->release();
  439. cs.unlock();
  440. return 1;
  441. }
  442. k->getNachricht((char*)&byteLän, 2); // sendelänge empfangen
  443. if (!byteLän)
  444. break;
  445. }
  446. else
  447. break;
  448. if (maxbps)
  449. {
  450. zMess->messungEnde();
  451. sec += zMess->getSekunden();
  452. zMess->messungStart();
  453. if (sec >= 1)
  454. {
  455. sec = 0;
  456. bps = 0;
  457. }
  458. while (bps >= maxbps)
  459. {
  460. Sleep(10);
  461. zMess->messungEnde();
  462. sec += zMess->getSekunden();
  463. zMess->messungStart();
  464. if (sec >= 1)
  465. {
  466. sec = 0;
  467. bps = 0;
  468. }
  469. }
  470. }
  471. }
  472. }
  473. zMess->release();
  474. delete[] bytes;
  475. k->sendeEncrypted("\1", 1);
  476. zielD->close();
  477. zielD->release();
  478. cs.unlock();
  479. return 1;
  480. }
  481. // Trennt die Verbindung zum Server
  482. // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
  483. // Sollte erst nach einem erfolgreichen Aufruf von verbinde aufgerufen werden
  484. bool PatchClient::trenne(bool abmelden)
  485. {
  486. cs.lock();
  487. verbinde();
  488. if (!k)
  489. {
  490. cs.unlock();
  491. return 1;
  492. }
  493. if (abmelden)
  494. {
  495. k->sendeEncrypted("\4", 1);
  496. char ret = 0;
  497. k->getNachrichtEncrypted(&ret, 1);
  498. if (ret == 3)
  499. { // error
  500. k->getNachrichtEncrypted(&ret, 1);
  501. char* msg = new char[ret + 1];
  502. msg[ret] = 0;
  503. if (ret)
  504. k->getNachrichtEncrypted(msg, ret);
  505. err = "error while unregister Client Patch Server returned: ";
  506. err += msg;
  507. delete[] msg;
  508. }
  509. }
  510. k->sendeEncrypted("\3", 1);
  511. char ret = 0;
  512. k->getNachrichtEncrypted(&ret, 1);
  513. if (ret == 3)
  514. { // error
  515. k->getNachrichtEncrypted(&ret, 1);
  516. char* msg = new char[ret + 1];
  517. msg[ret] = 0;
  518. if (ret)
  519. k->getNachrichtEncrypted(msg, ret);
  520. err = "error while trenne Patch Server returned: ";
  521. err += msg;
  522. delete[] msg;
  523. }
  524. k->trenne();
  525. k = (Network::Klient*)k->release();
  526. cs.unlock();
  527. return 1;
  528. }
  529. // Gibt 1 zurück, falls der Client verbunden ist, 0 sonst
  530. bool PatchClient::istVerbunden() const
  531. {
  532. return k != 0;
  533. }
  534. // Gibt die Anzahl von übertragenen Bytes seit dem letzten Aufruf zurück
  535. int PatchClient::getDownload() const
  536. {
  537. return k ? k->getDownloadBytes(1) : 0;
  538. }
  539. // gibt den Letzten Fehlertext zuück
  540. // sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist
  541. const char* PatchClient::getLetzterFehler() const
  542. {
  543. return err;
  544. }