#include "LoginClient.h" #include #include "Keys.h" #include #include using namespace KSGClient; // Inhalt der LoginClient Klasse // Konstruktor LoginClient::LoginClient(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; accountId = 0; } // Destruktor LoginClient::~LoginClient() { trenne(1); delete[] key; } // verbindet sich mit dem zugewiesenen Login Server // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst bool LoginClient::verbinde() { cs.lock(); if (k) { cs.unlock(); return 1; } k = new Network::Klient(); int l = 0; char* key; Keys::getServerKey(&key, l, Keys::LOGIN, Keys::SENDEN); k->setSendeKey(key, l); delete[] key; Keys::getServerKey(&key, l, Keys::LOGIN, 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 Login 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 Login Server"; k = (Network::Klient*)k->release(); cs.unlock(); return 0; } } else { err = "network error while connecting to Login Server"; k = (Network::Klient*)k->release(); cs.unlock(); return 0; } cs.unlock(); return 1; } // Der Client wird beim Serversystem in einen Account eingeloggt // gibt bei Erfolg 1 zurück, 2 falls en anderer Client in dem Account eingeloggt ist, 0 sonnst // Sollte erst nach einem erfolgreichen Aufruf von verbinde aufgerufen werden int LoginClient::login(const char* name, const char* pass) { cs.lock(); if (!k) { err = "Der Client ist nicht verbunden."; cs.unlock(); return 0; } k->sendeEncrypted("\5", 1); char serverReturn = 0; k->getNachrichtEncrypted(&serverReturn, 1); if (serverReturn == 1) { unsigned char byte = (unsigned char)textLength(name); k->sendeEncrypted((char*)&byte, 1); k->sendeEncrypted(name, byte); byte = (unsigned char)textLength(pass); k->sendeEncrypted((char*)&byte, 1); k->sendeEncrypted(pass, byte); k->getNachrichtEncrypted(&serverReturn, 1); if (serverReturn == 1) { char host[255] = ""; Network::getHostName(host, 255); Text* addresse = new Text(Network::getHostAddresse()); unsigned char localIp[4]; localIp[0] = TextZuInt(addresse->getText(), 10); localIp[1] = TextZuInt(addresse->getText() + addresse->positionVon('.', 0) + 1, 10); localIp[2] = TextZuInt(addresse->getText() + addresse->positionVon('.', 1) + 1, 10); localIp[3] = TextZuInt(addresse->getText() + addresse->positionVon('.', 2) + 1, 10); addresse = (Text*)addresse->release(); k->sendeEncrypted((char*)&localIp, 4); byte = textLength(host); k->sendeEncrypted((char*)&byte, 1); k->sendeEncrypted(host, byte); k->getNachrichtEncrypted((char*)&accountId, 4); cs.unlock(); return 1; } else if (serverReturn == 2) { k->sendeEncrypted("\0", 1); cs.unlock(); return 2; } } if (serverReturn == 3) { char byte = 0; k->getNachrichtEncrypted(&byte, 1); char* fehler = new char[byte + 1]; fehler[byte] = 0; k->getNachrichtEncrypted(fehler, byte); err = fehler; delete[]fehler; cs.unlock(); return 0; } err = "Unbekannter Fehler"; cs.unlock(); return 0; } // Diese Funktion wird in der Zukunft mal implementiert werden. Mit dem Geheimnis des Accounts können so andere Clients, welche bereits in dem Account eingeloggt werden rausgeschmissen werden. bool LoginClient::kick(const char* name, const char* pass, const char* geheim) { cs.lock(); if (!k) { err = "Der Client ist nicht verbunden."; cs.unlock(); return 0; } k->sendeEncrypted("\5", 1); char serverReturn = 0; k->getNachrichtEncrypted(&serverReturn, 1); if (serverReturn == 1) { unsigned char byte = (unsigned char)textLength(name); k->sendeEncrypted((char*)&byte, 1); k->sendeEncrypted(name, byte); byte = (unsigned char)textLength(pass); k->sendeEncrypted((char*)&byte, 1); k->sendeEncrypted(pass, byte); k->getNachrichtEncrypted(&serverReturn, 1); if (serverReturn == 2) { unsigned char byte = (unsigned char)textLength(geheim); k->sendeEncrypted((char*)&byte, 1); k->sendeEncrypted(geheim, byte); k->getNachrichtEncrypted((char*)&serverReturn, 1); if (!serverReturn) { cs.unlock(); return 0; } } if (serverReturn == 1 || serverReturn == 2) { char host[255]; Network::getHostName(host, 255); Text* addresse = new Text(Network::getHostAddresse()); unsigned char localIp[4]; localIp[0] = TextZuInt(addresse->getText(), 10); localIp[1] = TextZuInt(addresse->getText() + addresse->positionVon('.', 0) + 1, 10); localIp[2] = TextZuInt(addresse->getText() + addresse->positionVon('.', 1) + 1, 10); localIp[3] = TextZuInt(addresse->getText() + addresse->positionVon('.', 2) + 1, 10); addresse = (Text*)addresse->release(); k->sendeEncrypted((char*)&localIp, 4); byte = textLength(host); k->sendeEncrypted((char*)&byte, 1); k->sendeEncrypted(host, byte); k->getNachrichtEncrypted((char*)&accountId, 4); return 1; } } if (serverReturn == 3) { char byte = 0; k->getNachrichtEncrypted(&byte, 1); char* fehler = new char[byte + 1]; fehler[byte] = 0; k->getNachrichtEncrypted(fehler, byte); err = fehler; delete[]fehler; cs.unlock(); return 0; } err = "Unbekannter Fehler"; cs.unlock(); return 0; } // logt den Account aus // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst // sollte erst aufgerufen werden, nachdem ein erfolgreicher Aufruf von login erfolg ist bool LoginClient::logout() { cs.lock(); if (!k) { err = "Der Client ist nicht verbunden."; cs.unlock(); return 0; } k->sendeEncrypted("\6", 1); char serverReturn = 0; k->getNachrichtEncrypted(&serverReturn, 1); if (serverReturn == 1) { k->sendeEncrypted((char*)&accountId, 4); k->getNachrichtEncrypted(&serverReturn, 1); } if (serverReturn == 3) { char byte = 0; k->getNachrichtEncrypted(&byte, 1); char* fehler = new char[byte + 1]; fehler[byte] = 0; k->getNachrichtEncrypted(fehler, byte); err = fehler; delete[]fehler; 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 LoginClient::keepAlive() { char res = 0; if (!cs.tryLock()) return 1; if (!k) { err = "Der Client ist nicht verbunden."; cs.unlock(); return 0; } Framework::logLine((char*)"Verbindungstest zum Login Server..."); bool ok = k->sendeEncrypted("\x7", 1); ok &= k->getNachrichtEncrypted(&res, 1); cs.unlock(); if (res != 1 || !ok) { Framework::logLine((char*)"Verbindungsabbruch."); trenne(0); } 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 LoginClient::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 Login 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 Login 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 LoginClient::istVerbunden() const { return k != 0; } // Gibt die Id des Accounts zurück, in den sich der Client eingeloggt hat. // sollte erst aufgerufen werden, nachdem ein erfolgreicher Aufruf von login erfolg ist int LoginClient::getAccountId() const { return accountId; } // gibt den Letzten Fehlertext zuück // sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist const char* LoginClient::getLetzterFehler() const { return err; }