123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- #include "SpielClient.h"
- #include <Klient.h>
- #include "Keys.h"
- using namespace KSGClient;
- // Inhalt der SpielClient Klasse
- // Konstruktor
- SpielClient::SpielClient( int klientId, unsigned short port, char *ip, char *key, unsigned char keyLen )
- {
- ref = 1;
- this->ip = ip;
- this->port = port;
- cId = klientId;
- senden = 0;
- empfangen = 0;
- this->key = new char[ keyLen ];
- memcpy( this->key, key, keyLen );
- this->keyLen = keyLen;
- }
- // Destruktor
- SpielClient::~SpielClient()
- {
- trenne();
- delete[] key;
- }
- // verbindet sich mit dem zugewiesenen Karten Server
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::verbinde()
- {
- cs.lock();
- if( senden )
- {
- cs.unlock();
- return 1;
- }
- if( !senden )
- senden = new Network::Klient();
- int keyLen = 0;
- char *key = 0;
- Keys::getServerKey( &key, keyLen, Keys::SPIEL, Keys::SENDEN );
- senden->setSendeKey( key, keyLen );
- delete[] key;
- Keys::getServerKey( &key, keyLen, Keys::SPIEL, Keys::EMPFANGEN );
- senden->setEmpfangKey( key, keyLen );
- delete[] key;
- if( senden->verbinde( port, ip ) )
- {
- if( senden->sendeEncrypted( "\1", 1 ) )
- {
- char serverReturn = 0;
- senden->sendeEncrypted( (char*)&cId, 4 );
- char ret = 0;
- senden->getNachrichtEncrypted( &ret, 1 );
- if( ret != 1 )
- {
- if( ret == 3 )
- {
- char byte = 0;
- senden->getNachrichtEncrypted( &byte, 1 );
- char *f = new char[ byte + 1 ];
- f[ byte ] = 0;
- senden->getNachrichtEncrypted( f, byte );
- err = f;
- delete[]f;
- }
- senden->sendeEncrypted( "\3", 1 );
- senden->getNachrichtEncrypted( &serverReturn, 1 );
- senden->trenne();
- senden = senden->release();
- err = "Server akzeptiert den Klient nicht.";
- cs.unlock();
- return 0;
- }
- senden->setSendeKey( this->key, this->keyLen );
- senden->setEmpfangKey( this->key, this->keyLen );
- if( !empfangen )
- empfangen = new Network::Klient();
- int keyLen = 0;
- char *key = 0;
- Keys::getServerKey( &key, keyLen, Keys::SPIEL, Keys::SENDEN );
- empfangen->setSendeKey( key, keyLen );
- delete[] key;
- Keys::getServerKey( &key, keyLen, Keys::SPIEL, Keys::EMPFANGEN );
- empfangen->setEmpfangKey( key, keyLen );
- delete[] key;
- if( empfangen->verbinde( senden->getServerPort(), senden->getServerIp() ) )
- {
- empfangen->sendeEncrypted( "\1", 1 );
- empfangen->sendeEncrypted( (char*)&cId, 4 );
- char res = 0;
- empfangen->getNachrichtEncrypted( &res, 1 );
- if( res == 3 )
- {
- char län = 0;
- empfangen->getNachrichtEncrypted( &län, 1 );
- char *nachricht = new char[ län + 1 ];
- nachricht[ län ] = 0;
- empfangen->getNachrichtEncrypted( nachricht, län );
- err = nachricht;
- delete[] nachricht;
- }
- if( res == 1 )
- {
- empfangen->setSendeKey( this->key, this->keyLen );
- empfangen->setEmpfangKey( this->key, this->keyLen );
- }
- else if( res != 0 )
- {
- err = "Fehler beim Verbinden mit dem Spiel Server.";
- senden->sendeEncrypted( "\3", 1 );
- char serverReturn = 0;
- senden->getNachrichtEncrypted( &serverReturn, 1 );
- senden->trenne();
- senden = senden->release();
- empfangen->trenne();
- empfangen = empfangen->release();
- return 0;
- }
- cs.unlock();
- return 1;
- }
- else
- {
- empfangen = empfangen->release();
- senden->sendeEncrypted( "\3", 1 );
- char serverReturn = 0;
- senden->getNachrichtEncrypted( &serverReturn, 1 );
- senden->trenne();
- senden = senden->release();
- err = "Der dir zugewiesene Spiel Server kann dir keine Nachrichten senden.";
- cs.unlock();
- return 0;
- }
- }
- else
- {
- senden->trenne();
- senden = senden->release();
- err = "Der dir zugewiesene Spiel Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut.";
- cs.unlock();
- return 0;
- }
- }
- else
- {
- err = "Der dir zugewiesene Spiel Server antwortet nicht. Bitte versuche es Später erneut.";
- senden = senden->release();
- cs.unlock();
- return 0;
- }
- err = "Unbekannter Fehler";
- cs.unlock();
- return 0;
- }
- // Betritt das Vorgeschlagene Spiel
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::spielErstelltAnnehmen()
- {
- cs.lock();
- if( !senden )
- {
- err = "Der Client ist nicht verbunden.";
- cs.unlock();
- return 0;
- }
- char ret = 0;
- senden->sendeEncrypted( "\4", 1 );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( ret != 1 )
- err = "Fehler beim annehmen des Spiels.";
- cs.unlock();
- return ret == 1;
- }
- // Lehnt das Vorgeschlagene Spiel ab
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::spielErstelltAblehnen()
- {
- cs.lock();
- if( !senden )
- {
- err = "Der Client ist nicht verbunden.";
- cs.unlock();
- return 0;
- }
- char ret = 0;
- senden->sendeEncrypted( "\5", 1 );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( ret != 1 )
- err = "Fehler beim ablehnen des Spiels.";
- cs.unlock();
- return ret == 1;
- }
- // Wechselt zu einem bestimmten Team
- // team: Die Id des teams
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::spielErstelltTeamWechseln( int team )
- {
- cs.lock();
- if( !senden )
- {
- err = "Der Client ist nicht verbunden.";
- cs.unlock();
- return 0;
- }
- char ret = 0;
- senden->sendeEncrypted( "\6", 1 );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( !ret )
- {
- err = "Fehler beim wechseln des Teams.";
- cs.unlock();
- return 0;
- }
- senden->sendeEncrypted( (char*)&team, 4 );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( ret != 1 )
- err = "Fehler beim wechseln des Teams.";
- cs.unlock();
- return ret == 1;
- }
- // Bestätigt die Teamauswahl so dass das Spiel früher beginnen kann
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::spielErstelltTeamFertig()
- {
- cs.lock();
- if( !senden )
- {
- err = "Der Client ist nicht verbunden.";
- cs.unlock();
- return 0;
- }
- char ret = 0;
- senden->sendeEncrypted( "\xE", 1 );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( ret != 1 )
- err = "Fehler beim setzen der Bereitschaft.";
- cs.unlock();
- return ret == 1;
- }
- // sendet eine Chat Nachricht an die mitglieder des erstellten Spiels
- // nachricht: Die Nachricht
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::spielErstelltChatNachricht( char *nachricht )
- {
- char län = textLength( nachricht );
- if( !län )
- return 1;
- cs.lock();
- if( !senden )
- {
- err = "Der Client ist nicht verbunden.";
- cs.unlock();
- return 0;
- }
- char ret = 0;
- senden->sendeEncrypted( "\7", 1 );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( !ret )
- {
- err = "Fehler beim senden der Chat Nachricht.";
- cs.unlock();
- return 0;
- }
- senden->sendeEncrypted( &län, 1 );
- senden->sendeEncrypted( nachricht, län );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( ret != 1 )
- err = "Fehler beim senden der Chat Nachricht.";
- cs.unlock();
- return ret == 1;
- }
- // Teilt dem Server mit, dass der Client bereit ist das Spiel zu laden
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::bereitZumLaden()
- {
- cs.lock();
- if( !senden )
- {
- err = "Der Client ist nicht verbunden.";
- cs.unlock();
- return 0;
- }
- char ret = 0;
- senden->sendeEncrypted( "\x9", 1 );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( ret != 1 )
- err = "Fehler beim setzen der Bereitschaft.";
- cs.unlock();
- return ret == 1;
- }
- // Teilt dem Server mit, zu wie viel Prozent der Client das Spiel geladen hat
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::setLadenProzent( int prozent )
- {
- cs.lock();
- if( !senden )
- {
- err = "Der Client ist nicht verbunden.";
- cs.unlock();
- return 0;
- }
- char ret = 0;
- senden->sendeEncrypted( "\xC", 1 );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( ret )
- {
- senden->sendeEncrypted( (char*)&prozent, 4 );
- senden->getNachrichtEncrypted( &ret, 1 );
- }
- if( ret != 1 )
- err = "Fehler beim setzen des Fortschritts.";
- cs.unlock();
- return ret == 1;
- }
- // Teilt dem Server mit, dass das Spiel fertig geladen wurde
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::bereitZumSpiel()
- {
- cs.lock();
- if( !senden )
- {
- err = "Der Client ist nicht verbunden.";
- cs.unlock();
- return 0;
- }
- char ret = 0;
- senden->sendeEncrypted( "\xA", 1 );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( ret != 1 )
- err = "Fehler beim setzen der Bereitschaft.";
- cs.unlock();
- return ret == 1;
- }
- // Sendet während des Spiels eine Nachricht an den Server
- // län: Die Länge der Nachricht
- // bytes: Ein Zeiger auf die Nachricht
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::spielNachricht( short län, char *bytes )
- {
- cs.lock();
- if( !senden )
- {
- err = "Der Client ist nicht verbunden.";
- cs.unlock();
- return 0;
- }
- senden->sendeEncrypted( "\xB", 1 );
- senden->sende( (char*)&län, 2 );
- senden->sende( bytes, län );
- cs.unlock();
- return 1;
- }
- // Sendet während der Statistik eine Nachricht an den Server
- // län: Die Länge der Nachricht
- // bytes: Ein Zeiger auf die Nachricht
- // Gibt 1 zurück, falls der Vorgang erfolgreich ist, 0 sonnst
- bool SpielClient::statistikNachricht( short län, char *bytes )
- {
- cs.lock();
- if( !senden )
- {
- err = "Der Client ist nicht verbunden.";
- cs.unlock();
- return 0;
- }
- char ret = 0;
- senden->sendeEncrypted( "\xD", 1 );
- senden->getNachrichtEncrypted( &ret, 1 );
- if( ret )
- {
- senden->sendeEncrypted( (char*)&län, 2 );
- senden->sendeEncrypted( bytes, län );
- senden->getNachrichtEncrypted( &ret, 1 );
- }
- if( ret != 1 )
- err = "Fehler beim setzen der Statistik Nachricht.";
- cs.unlock();
- return ret == 1;
- }
- // Wartet auf eine Nachricht vom Spiel Server.
- // Gibt bei Erfolg 1 zurück, 0 sonnst
- // nachricht: Eine Referenz auf die Struktur, in der die Nachricht gespeichert werden soll
- bool SpielClient::getNextMessage( SpielServerNachricht &nachricht )
- {
- do
- {
- if( !empfangen->getNachrichtEncrypted( &nachricht.type, 1 ) )
- {
- err = "Es ist ein Fehler beim Empfangen aufgetreten";
- return 0;
- }
- switch( nachricht.type )
- {
- case 0: // verbindung getrennt
- trenne();
- break;
- case 1: // verbleibende Zeit
- empfangen->getNachrichtEncrypted( &nachricht.sekunden, 1 );
- break;
- case 2: // SpielErstellt abbruch
- if( 1 )
- {
- char län = 0;
- empfangen->getNachrichtEncrypted( &län, 1 );
- char *grund = new char[ län + 1 ];
- grund[ län ] = 0;
- empfangen->getNachrichtEncrypted( grund, län );
- nachricht.message = grund;
- delete[] grund;
- }
- break;
- case 3: // Fehler
- if( 1 )
- {
- char länge = 0;
- empfangen->getNachrichtEncrypted( &länge, 1 );
- char *txt = new char[ länge + 1 ];
- txt[ länge ] = 0;
- empfangen->getNachrichtEncrypted( txt, länge );
- nachricht.message = txt;
- delete[]txt;
- }
- break;
- case 4: // zurück in Warteschlange
- empfangen->getNachrichtEncrypted( &nachricht.stunden, 1 );
- empfangen->getNachrichtEncrypted( &nachricht.minuten, 1 );
- empfangen->getNachrichtEncrypted( &nachricht.sekunden, 1 );
- break;
- case 6: // SpielErstellt Initialisierung
- empfangen->getNachrichtEncrypted( (char*)&nachricht.sts->spielerAnzahl, 4 );
- empfangen->getNachrichtEncrypted( (char*)&nachricht.sts->teamAnzahl, 4 );
- for( int i = 0; i < nachricht.sts->spielerAnzahl; i++ )
- {
- int farbe = 0;
- empfangen->getNachrichtEncrypted( (char*)&farbe, 4 );
- nachricht.sts->spielerFarbe->set( farbe, i );
- }
- for( int i = 0; i < nachricht.sts->teamAnzahl; i++ )
- {
- int farbe = 0;
- empfangen->getNachrichtEncrypted( (char*)&farbe, 4 );
- nachricht.sts->teamFarbe->set( farbe, i );
- }
- for( int i = 0; i < nachricht.sts->teamAnzahl; i++ )
- {
- char län = 0;
- empfangen->getNachrichtEncrypted( &län, 1 );
- char *name = new char[ län + 1 ];
- name[ län ] = 0;
- if( län )
- empfangen->getNachrichtEncrypted( name, län );
- Text *tmp = new Text( name );
- delete[] name;
- nachricht.sts->teamName->set( tmp, i );
- }
- for( int i = 0; i < nachricht.sts->teamAnzahl; i++ )
- {
- int größe = 0;
- empfangen->getNachrichtEncrypted( (char*)&größe, 4 );
- nachricht.sts->teamSize->set( größe, i );
- }
- break;
- case 7: // SpielErstellt Spieler hinzugefügt
- empfangen->getNachrichtEncrypted( (char*)&nachricht.accountId, 4 );
- break;
- case 8: // SpielErstellt Spieler entfernt
- empfangen->getNachrichtEncrypted( (char*)&nachricht.accountId, 4 );
- break;
- case 9: // SpielErstellt Spieler wechselt Team
- empfangen->getNachrichtEncrypted( (char*)&nachricht.accountId, 4 );
- empfangen->getNachrichtEncrypted( (char*)&nachricht.spielerNummer, 4 );
- break;
- case 0xA: // SpielErstellt Chat Nachricht
- if( 1 )
- {
- char län = 0;
- empfangen->getNachrichtEncrypted( &län, 1 );
- char *txt = new char[ län + 1 ];
- txt[ län ] = 0;
- if( län )
- empfangen->getNachrichtEncrypted( txt, län );
- nachricht.message = txt;
- delete[] txt;
- }
- break;
- case 0xB: // Spiel gefunden
- empfangen->getNachrichtEncrypted( (char*)&nachricht.karteId, 4 );
- break;
- case 0xD: // Spiel Laden Spieler hinzufügen
- empfangen->getNachrichtEncrypted( (char*)&nachricht.accountId, 4 );
- empfangen->getNachrichtEncrypted( (char*)&nachricht.spielerNummer, 4 );
- break;
- case 0xE: // Spiel Laden Spieler Prozent
- empfangen->getNachrichtEncrypted( (char*)&nachricht.accountId, 4 );
- empfangen->getNachrichtEncrypted( (char*)&nachricht.prozent, 4 );
- break;
- case 0xF: // Spiel Laden Spieler Ping
- empfangen->getNachrichtEncrypted( (char*)&nachricht.accountId, 4 );
- empfangen->getNachrichtEncrypted( (char*)&nachricht.ping, 4 );
- break;
- case 0x10: // ping
- empfangen->sendeEncrypted( "\1", 1 );
- break;
- case 0x12: // Spiel Nachricht
- empfangen->getNachricht( (char*)&nachricht.län, 2 );
- nachricht.data = new char[ nachricht.län ];
- empfangen->getNachricht( nachricht.data, nachricht.län );
- break;
- case 0x13: // Statistik Nachricht
- empfangen->getNachrichtEncrypted( (char*)&nachricht.län, 2 );
- nachricht.data = new char[ nachricht.län ];
- empfangen->getNachrichtEncrypted( nachricht.data, nachricht.län );
- break;
- case 0x14: // ping
- empfangen->sendeEncrypted( "\1", 1 );
- break;
- }
- } while( nachricht.type == 0x10 || nachricht.type == 0x14 );
- 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 SpielClient::keepAlive()
- {
- if( !senden )
- return 0;
- char res = 0;
- if( !cs.tryLock() )
- return 1;
- bool ok = senden->sendeEncrypted( "\xF", 1 );
- ok &= senden->getNachrichtEncrypted( &res, 1 );
- cs.unlock();
- if( res != 1 || !ok )
- {
- err = "Die Verbindung zum Spiel Server ist abgebrochen.";
- trenne();
- return 0;
- }
- 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 SpielClient::trenne()
- {
- cs.lock();
- if( !senden )
- {
- cs.unlock();
- return 1;
- }
- senden->sendeEncrypted( "\3", 1 );
- char serverReturn = 0;
- senden->getNachrichtEncrypted( &serverReturn, 1 );
- senden->trenne();
- senden = senden->release();
- empfangen->trenne();
- empfangen = empfangen->release();
- cs.unlock();
- return 1;
- }
- // Gibt 1 zurück, falls der Client verbunden ist, 0 sonst
- bool SpielClient::istVerbunden() const
- {
- return senden != 0;
- }
- // gibt den Letzten Fehlertext zuück
- // sollte erst aufgerufen werden, nachdem eine andere aufgerufene Methode fehlgeschlagen ist
- char *SpielClient::getLetzterFehler() const
- {
- return err;
- }
- // Erhöht den Reference Counter um 1 un gibt this zurück
- SpielServerClient *SpielClient::getThis()
- {
- ref++;
- return this;
- }
- // Verringert den Reference Counter um 1 und gibt 0 zurück.
- // Falls der Reference Counter nach dem Aufruf auf 0 ist löscht sich das Objekt selbst
- SpielServerClient *SpielClient::release()
- {
- if( !--ref )
- delete this;
- return 0;
- }
|