#include "KartenClient.h" #include "Keys.h" #include #include #include using namespace KSGClient; // Inhalt der KartenClient Klasse // Konstruktor KartenClient::KartenClient(int klientId, unsigned short port, const char* ip, const char* key, unsigned char keyLen) : ReferenceCounter() { this->ip = ip; this->port = port; cId = klientId; k = 0; this->key = new char[keyLen]; memcpy(this->key, key, keyLen); this->keyLen = keyLen; } // Destruktor KartenClient::~KartenClient() { trenne(1); delete[] key; } // verbindet sich mit dem zugewiesenen Karten Server // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst bool KartenClient::verbinde() { cs.lock(); if (k) { cs.unlock(); return 1; } k = new Network::Klient(); int l = 0; char* key; Keys::getServerKey(&key, l, Keys::KARTEN, Keys::SENDEN); k->setSendeKey(key, l); delete[] key; Keys::getServerKey(&key, l, Keys::KARTEN, 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 Karten 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 Karten Server"; k = (Network::Klient*)k->release(); cs.unlock(); return 0; } } else { err = "network error while connecting to Karten Server"; k = (Network::Klient*)k->release(); cs.unlock(); return 0; } cs.unlock(); return 1; } // lädt eine Karte herunter und speichert sie unter data/tmp/Karten/{id}/spiel // id: Die Id der Karte // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst bool KartenClient::downloadKarte(int id) { cs.lock(); if (!k) { err = "Der Client ist nicht verbunden."; cs.unlock(); return 0; } k->sendeEncrypted("\x6", 1); char ret = 0; k->getNachrichtEncrypted(&ret, 1); if (ret == 1) { k->sendeEncrypted((char*)&id, 4); k->getNachrichtEncrypted(&ret, 1); if (ret == 2) { // update err = "Die Karte wird momentan aktualisiert."; cs.unlock(); return 0; } else if (ret == 1) { int anz = 0; k->getNachrichtEncrypted((char*)&anz, 4); for (int i = 0; i < anz; i++) { char län = 0; k->getNachrichtEncrypted(&län, 1); if (!län) continue; char* pf = new char[län + 1]; pf[län] = 0; k->getNachrichtEncrypted(pf, län); __int64 größe = 0; k->getNachrichtEncrypted((char*)&größe, 8); char* buffer = new char[2048]; Text pfad = "data/tmp/Karten/"; pfad += id; pfad += "/spiel"; pfad += pf; delete[] pf; Datei d; d.setDatei(pfad); d.erstellen(); d.open(Datei::Style::schreiben); while (größe) { int l = größe >= 2048 ? 2048 : (int)größe; k->getNachricht(buffer, l); d.schreibe(buffer, l); größe -= l; } d.close(); delete[] buffer; } } } if (ret == 3) { char byte = 0; k->getNachrichtEncrypted(&byte, 1); char* f = new char[byte + 1]; f[byte] = 0; k->getNachrichtEncrypted(f, byte); err = f; delete[] f; cs.unlock(); return 0; } cs.unlock(); return 1; } // lädt das Titelbild Karte herunter und speichert es unter data/tmp/Karten/{id}/titel.ltdb // id: Die Id der Karte // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst bool KartenClient::downloadKarteTitel(int id) { cs.lock(); if (!k) { err = "Der Client ist nicht verbunden."; cs.unlock(); return 0; } k->sendeEncrypted("\x8", 1); char ret = 0; k->getNachrichtEncrypted(&ret, 1); if (ret == 1) { k->sendeEncrypted((char*)&id, 4); k->getNachrichtEncrypted(&ret, 1); if (ret == 2) { // update err = "Die Karte wird momentan aktualisiert."; cs.unlock(); return 0; } else if (ret == 1) { __int64 größe = 0; k->getNachrichtEncrypted((char*)&größe, 8); char* buffer = new char[2048]; Text pfad = "data/tmp/Karten/"; pfad += id; pfad += "/titel.ltdb"; Datei d; d.setDatei(pfad); d.erstellen(); d.open(Datei::Style::schreiben); while (größe) { int l = größe >= 2048 ? 2048 : (int)größe; k->getNachricht(buffer, l); d.schreibe(buffer, l); größe -= l; } d.close(); delete[] buffer; } } if (ret == 3) { char byte = 0; k->getNachrichtEncrypted(&byte, 1); char* f = new char[byte + 1]; f[byte] = 0; k->getNachrichtEncrypted(f, byte); err = f; delete[] f; cs.unlock(); return 0; } cs.unlock(); return 1; } // lädt die Beschreibung Karte herunter und speichert sie unter data/tmp/Karten/{id}/beschreibung.ksgs // id: Die Id der Karte // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst bool KartenClient::downloadKarteBeschreibung(int id) { cs.lock(); if (!k) { err = "Der Client ist nicht verbunden."; cs.unlock(); return 0; } k->sendeEncrypted("\x9", 1); char ret = 0; k->getNachrichtEncrypted(&ret, 1); if (ret == 1) { k->sendeEncrypted((char*)&id, 4); k->getNachrichtEncrypted(&ret, 1); if (ret == 2) { // update err = "Die Karte wird momentan aktualisiert."; cs.unlock(); return 0; } else if (ret == 1) { __int64 größe = 0; k->getNachrichtEncrypted((char*)&größe, 8); char* buffer = new char[2048]; Text pfad = "data/tmp/Karten/"; pfad += id; pfad += "/beschreibung.ksgs"; Datei d; d.setDatei(pfad); d.erstellen(); d.open(Datei::Style::schreiben); while (größe) { int l = größe >= 2048 ? 2048 : (int)größe; k->getNachricht(buffer, l); d.schreibe(buffer, l); größe -= l; } d.close(); delete[] buffer; } } if (ret == 3) { char byte = 0; k->getNachrichtEncrypted(&byte, 1); char* f = new char[byte + 1]; f[byte] = 0; k->getNachrichtEncrypted(f, byte); err = f; delete[] f; cs.unlock(); return 0; } cs.unlock(); return 1; } // lädt die Minimap Karte herunter und speichert es unter data/tmp/Karten/{id}/minimap.ltdb // id: Die Id der Karte // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst bool KartenClient::downloadKarteMinimap(int id) { cs.lock(); if (!k) { err = "Der Client ist nicht verbunden."; cs.unlock(); return 0; } k->sendeEncrypted("\xA", 1); char ret = 0; k->getNachrichtEncrypted(&ret, 1); if (ret == 1) { k->sendeEncrypted((char*)&id, 4); k->getNachrichtEncrypted(&ret, 1); if (ret == 2) { // update err = "Die Karte wird momentan aktualisiert."; cs.unlock(); return 0; } else if (ret == 1) { __int64 größe = 0; k->getNachrichtEncrypted((char*)&größe, 8); char* buffer = new char[2048]; Text pfad = "data/tmp/Karten/"; pfad += id; pfad += "/minimap.ltdb"; Datei d; d.setDatei(pfad); d.erstellen(); d.open(Datei::Style::schreiben); while (größe) { int l = größe >= 2048 ? 2048 : (int)größe; k->getNachricht(buffer, l); d.schreibe(buffer, l); größe -= l; } d.close(); delete[] buffer; } } if (ret == 3) { char byte = 0; k->getNachrichtEncrypted(&byte, 1); char* f = new char[byte + 1]; f[byte] = 0; k->getNachrichtEncrypted(f, byte); err = f; delete[] f; cs.unlock(); return 0; } cs.unlock(); return 1; } // lädt das Ladebild Karte herunter und speichert es unter data/tmp/Karten/{id}/ladebild.ltdb // id: Die Id der Karte // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst bool KartenClient::downloadKarteLadebild(int id) { cs.lock(); if (!k) { err = "Der Client ist nicht verbunden."; cs.unlock(); return 0; } k->sendeEncrypted("\xB", 1); char ret = 0; k->getNachrichtEncrypted(&ret, 1); if (ret == 1) { k->sendeEncrypted((char*)&id, 4); k->getNachrichtEncrypted(&ret, 1); if (ret == 2) { // update err = "Die Karte wird momentan aktualisiert."; cs.unlock(); return 0; } else if (ret == 1) { __int64 größe = 0; k->getNachrichtEncrypted((char*)&größe, 8); char* buffer = new char[2048]; Text pfad = "data/tmp/Karten/"; pfad += id; pfad += "/ladebild.ltdb"; Datei d; d.setDatei(pfad); d.erstellen(); d.open(Datei::Style::schreiben); while (größe) { int l = größe >= 2048 ? 2048 : (int)größe; k->getNachricht(buffer, l); d.schreibe(buffer, l); größe -= l; } d.close(); delete[] buffer; } } if (ret == 3) { char byte = 0; k->getNachrichtEncrypted(&byte, 1); char* f = new char[byte + 1]; f[byte] = 0; k->getNachrichtEncrypted(f, byte); err = f; delete[] f; cs.unlock(); return 0; } cs.unlock(); return 1; } // Erhält die Verbindung aufrecht // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst // Sollte während einer bestehenden Verbindung etwa einmal alle 60 Sekunden aufgerufen werden, da sonst der Router die Verbindung automatisch trennt bool KartenClient::keepAlive() { if (!k) return 0; char res = 0; if (!cs.tryLock()) return 1; Framework::logLine((char*)"Verbindungstest zum Karten Server..."); bool ok = k->sendeEncrypted("\x5", 1); ok &= k->getNachrichtEncrypted(&res, 1); cs.unlock(); if (res != 1 || !ok) { Framework::logLine((char*)"Verbindungsabbruch."); trenne(0); err = "Verbindung unterbrochen: 'Keep Alive' nicht erfolgreich."; } else Framework::logLine((char*)"Verbindung besteht."); return res == 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 KartenClient::trenne(bool abmelden) { cs.lock(); verbinde(); if (!k) { cs.unlock(); return 1; } if (abmelden) { k->sendeEncrypted("\4", 1); char ret = 0; k->getNachrichtEncrypted(&ret, 1); if (ret == 3) { // error k->getNachrichtEncrypted(&ret, 1); char* msg = new char[ret + 1]; msg[ret] = 0; if (ret) k->getNachrichtEncrypted(msg, ret); err = "error while unregister Client Karten Server returned: "; err += msg; delete[] msg; } } k->sendeEncrypted("\3", 1); char ret = 0; k->getNachrichtEncrypted(&ret, 1); if (ret == 3) { // error k->getNachrichtEncrypted(&ret, 1); char* msg = new char[ret + 1]; msg[ret] = 0; if (ret) k->getNachrichtEncrypted(msg, ret); err = "error while trenne Karten Server returned: "; err += msg; delete[] msg; } k->trenne(); k = (Network::Klient*)k->release(); cs.unlock(); return 1; } // Gibt 1 zurück, falls der Client verbunden ist, 0 sonst bool KartenClient::istVerbunden() const { return k != 0; } // gibt den Letzten Fehlertext zuück // sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist const char* KartenClient::getLetzterFehler() const { return err; }