#include "HistorieClient.h" #include "Keys.h" #include #include using namespace KSGClient; // Inhalt der HistorieClient Klasse // Konstruktor HistorieClient::HistorieClient(int klientId, unsigned short port, const char* ip, const char* key, unsigned char keyLen, int spielId) : ReferenceCounter() { this->ip = ip; this->port = port; cId = klientId; k = 0; this->key = new char[keyLen]; memcpy(this->key, key, keyLen); this->keyLen = keyLen; this->spielId = spielId; } // Destruktor HistorieClient::~HistorieClient() { trenne(1); delete[] key; } // verbindet sich mit dem zugewiesenen Historie Server // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst bool HistorieClient::verbinde() { cs.lock(); if (k) { cs.unlock(); return 1; } k = new Network::Klient(); int l = 0; char* key; Keys::getServerKey(&key, l, Keys::HISTORIE, Keys::SENDEN); k->setSendeKey(key, l); delete[] key; Keys::getServerKey(&key, l, Keys::HISTORIE, Keys::EMPFANGEN); k->setEmpfangKey(key, l); delete[] key; if (k->verbinde(port, ip)) { if (k->sendeEncrypted("\1", 1)) { k->sendeEncrypted((char*)&cId, 4); char serverReturn = 0; k->getNachrichtEncrypted(&serverReturn, 1); if (serverReturn == 3) { char byte = 0; k->getNachrichtEncrypted(&byte, 1); char* f = new char[byte + 1]; f[byte] = 0; k->getNachrichtEncrypted(f, byte); err = "error while identifying client Historie Server returned: "; err += f; delete[]f; trenne(0); cs.unlock(); return 0; } k->setSendeKey(this->key, this->keyLen); k->setEmpfangKey(this->key, this->keyLen); } else { err = "network error while sending to Historie Server"; k = (Network::Klient*)k->release(); cs.unlock(); return 0; } } else { err = "network error while connecting to Historie Server"; k = (Network::Klient*)k->release(); cs.unlock(); return 0; } cs.unlock(); return 1; } // Trennt die Verbindung zum Server // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst // Sollte erst nach einem erfolgreichen Aufruf von verbinde aufgerufen werden bool HistorieClient::trenne(bool abmelden) { if (!k && !abmelden) return 1; if (!k && abmelden) verbinde(); if (!k) return 0; char serverReturn; if (abmelden) { k->sendeEncrypted("\4", 1); k->getNachrichtEncrypted(&serverReturn, 1); if (serverReturn == 3) { char län = 0; k->getNachrichtEncrypted(&län, 1); char* nachricht = new char[län + 1]; nachricht[län] = 0; k->getNachrichtEncrypted(nachricht, län); err = nachricht; delete[]nachricht; } } k->sendeEncrypted("\3", 1); k->getNachrichtEncrypted(&serverReturn, 1); k->trenne(); k = (Network::Klient*)k->release(); return 1; } // Lädt die Spiel Aufzeichnung eines Spiels herunter und speichert sie unter data/tmp/historie/{spielId} // Die Spielid wurde dem Objekt zum Zeitpunkt der Erstellung vom Information Server mitgegeben // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst // Diese Funktion verbindet sich selbstständig mit dem Server und trennt die Verbindung nach Beendigung des Vorgangs bool HistorieClient::downloadSpielHistorie() { if (DateiIstVerzeichnis(Text("data/tmp/historie/") += spielId)) return 1; cs.lock(); if (!verbinde()) { cs.unlock(); return 0; } k->sendeEncrypted("\6", 1); char ret = 0; k->getNachrichtEncrypted(&ret, 1); if (ret == 1) { k->sendeEncrypted((char*)&spielId, 4); k->getNachrichtEncrypted(&ret, 1); if (ret == 1) { char län = 0; k->getNachrichtEncrypted(&län, 1); while (län) { char* pf = new char[län + 1]; pf[län] = 0; k->getNachrichtEncrypted(pf, län); __int64 gr = 0; k->getNachrichtEncrypted((char*)&gr, 8); Text* pfad = new Text("data/tmp/historie/"); pfad->append(spielId); pfad->append(pf); delete[] pf; Datei* d = new Datei(); d->setDatei(pfad); d->erstellen(); d->open(Datei::Style::schreiben); char* bytes = new char[2048]; while (gr) { int dLän = gr > 2048 ? 2048 : (int)gr; k->getNachricht(bytes, dLän); d->schreibe(bytes, dLän); gr -= dLän; } delete[] bytes; d->close(); d->release(); k->getNachrichtEncrypted(&län, 1); } trenne(0); cs.unlock(); return 1; } } if (ret == 3) { char län = 0; k->getNachrichtEncrypted(&län, 1); char* nachricht = new char[län + 1]; nachricht[län] = 0; k->getNachrichtEncrypted(nachricht, län); err = nachricht; delete[]nachricht; trenne(0); cs.unlock(); return 0; } err = "unbekannter Fehler"; trenne(0); cs.unlock(); return 0; } // gibt den Letzten Fehlertext zuück // sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist const char* HistorieClient::getLetzterFehler() const { return err; }