#ifdef WIN32 #include "..\SpielServer.h" #include "..\..\Datenbank\Datenbank.h" #else #include "SpielServer.h" #include "Datenbank.h" #include #define Sleep( x ) usleep( (x) * 1000 ) #endif #include // Inhalt der SpielErstellt Kasse aus SpielErstellt.h // Konstruktor SpielErstellt::SpielErstellt(int id, SpielServer* ss) : Thread() { this->ss = ss; this->id = id; karte = ss->zDB()->getKarteVonErstelltemSpiel(id); spielArt = ss->zDB()->getSpielArtId(karte); accounts = new Array< int >(); spielerAnzahl = ss->zDB()->getSpielErstelltSpieler(id, accounts); klients = new RCArray< SSKlient >(); status = new Array< int >(); verbunden = 0; state = 0; abbr = 0; spielId = 0; } // Destruktor SpielErstellt::~SpielErstellt() { ss->release(); accounts->release(); klients->release(); status->release(); } // nicht constant void SpielErstellt::abbruch() { abbr = 1; } void SpielErstellt::sendeVerbindungsBefehl() { unsigned short sPort = (unsigned short)ss->getPort(); const char* sIp = ss->getIp(); unsigned char* sIp4 = new unsigned char[4]; Text* tmpT = new Text(sIp); Text* ip1 = tmpT->getTeilText(0, tmpT->positionVon('.')); Text* ip2 = tmpT->getTeilText(tmpT->positionVon('.') + 1, tmpT->positionVon('.', 1)); Text* ip3 = tmpT->getTeilText(tmpT->positionVon('.', 1) + 1, tmpT->positionVon('.', 2)); Text* ip4 = tmpT->getTeilText(tmpT->positionVon('.', 2) + 1); sIp4[0] = (unsigned char)TextZuInt(ip1->getText(), 10); sIp4[1] = (unsigned char)TextZuInt(ip2->getText(), 10); sIp4[2] = (unsigned char)TextZuInt(ip3->getText(), 10); sIp4[3] = (unsigned char)TextZuInt(ip4->getText(), 10); ip1->release(); ip2->release(); ip3->release(); ip4->release(); tmpT->release(); for (int i = 0; i < spielerAnzahl; i++) { int accId = accounts->hat(i) ? accounts->get(i) : 0; int port = 0; Text* ip = new Text(""); if (ss->zDB()->getChatServerPortIp(accId, &port, ip)) { char ret = 0; Klient* klient = new Klient(); unsigned char key[20] = { 78, 20, 190, 133, 10, 175, 51, 96, 62, 1, 180, 194, 126, 50, 211, 154, 105, 227, 22, 101 }; klient->setSendeKey((char*)key, 20); klient->setEmpfangKey((char*)key, 20); klient->verbinde((unsigned short)port, ip->getText()); klient->sendeEncrypted("\5\x1D", 2); klient->getNachrichtEncrypted(&ret, 1); if (ret != 3) { klient->sendeEncrypted((char*)&accId, 4); klient->sendeEncrypted((char*)&sPort, 2); klient->sendeEncrypted((char*)sIp4, 4); klient->getNachrichtEncrypted(&ret, 1); } if (ret == 3) { unsigned char len = 0; klient->getNachrichtEncrypted((char*)&len, 1); char* err = new char[len]; klient->getNachrichtEncrypted(err, len); delete[] err; } klient->sendeEncrypted("\3", 1); klient->getNachrichtEncrypted(&ret, 1); ss->addEmpfangen(klient->getDownloadBytes(1)); ss->addGesendet(klient->getUploadBytes(1)); klient->trenne(); klient->release(); } ip->release(); } delete[] sIp4; start(); } bool SpielErstellt::klientVerbunden(SSKlient* klient) { if (verbunden == spielerAnzahl) { klient->release(); return 0; } int accId = klient->getAccountId(); bool ret = 0; for (int i = 0; i < spielerAnzahl; i++) { if (accounts->hat(i) && accounts->get(i) == accId) { if (state == 1) klient->spielGefunden(karte); while (!klients->hat(i)) klients->add(0); klients->set(klient, i); while (!status->hat(i)) status->add(0); status->set(1, i); verbunden++; klient->setSpielErstellt(this); ret = 1; break; } } if (!ret) klient->release(); return ret; } bool SpielErstellt::klientNimmtAn(int accountId) { if (!verbunden || state != 1) return 0; bool ret = 0; for (int i = 0; i < spielerAnzahl; i++) { if (accounts->hat(i) && accounts->get(i) == accountId) { while (!status->hat(i)) status->add(0); status->set(2, i); ret = 1; break; } } return ret; } bool SpielErstellt::klientLehntAb(int accountId) { if (!verbunden || state != 1) return 0; bool ret = 0; for (int i = 0; i < spielerAnzahl; i++) { if (accounts->hat(i) && accounts->get(i) == accountId) { while (!status->hat(i)) status->add(0); status->set(3, i); ret = 1; break; } } return ret; } bool SpielErstellt::klientGetrennt(SSKlient* zKlient) { if (!verbunden) return 0; int accId = zKlient->getAccountId(); bool ret = 0; for (int i = 0; i < spielerAnzahl; i++) { if (accounts->hat(i) && accounts->get(i) == accId) { if (status->hat(i) && status->get(i) != 0) { zKlient->setSpielErstellt(0); while (!status->hat(i)) status->add(0); status->set(0, i); verbunden--; while (!klients->hat(i)) klients->add(0); klients->set(0, i); ret = 1; } break; } } return ret; } void SpielErstellt::thread() { state = 1; double time = 0; ZeitMesser* zeit = new ZeitMesser(); int nachrichtSenden = 1; while (time < 10) { // warten auf annahme von allen Spielern if (abbr) break; zeit->messungStart(); Sleep(100); bool br = 0; bool st2 = 1; for (int i = 0; i < spielerAnzahl; i++) { if (status->hat(i) && status->get(i) == 3) { br = 1; for (int j = 0; j < spielerAnzahl; j++) { if (j != i) { while (!status->hat(j)) status->add(0); status->set(2, j); } } break; } if (st2) st2 = status->hat(i) && status->get(i) == 2; } if (st2) br = 1; if (br) { zeit->messungEnde(); break; } char verbleibend = (char)(10 - (char)time); if (verbleibend < 0) verbleibend = 0; if (time > nachrichtSenden) { for (int i = 0; i < spielerAnzahl; i++) { if (status->hat(i) && status->get(i) != 0) { SSKlient* tmp = klients->z(i); if (tmp) tmp->zeitVerbleibend(verbleibend); } } nachrichtSenden++; } zeit->messungEnde(); time += zeit->getSekunden(); } // prüfen ob alle Spieler bereit sind state = 2; bool abbruch = verbunden != spielerAnzahl; const char* err = "Ein Spieler konnte nicht erreicht werden."; if (!abbruch) { for (int i = 0; i < spielerAnzahl; i++) { if (!status->hat(i) || status->get(i) != 2) { abbruch = 1; err = "Ein Spieler ist noch nicht bereit."; break; } } } if (abbr) { err = "Das Spiel wurde Wegen abwesenheit eines Spielers Abgebrochen."; abbruch = 1; for (int j = 0; j < spielerAnzahl; j++) { while (!status->hat(j)) status->add(0); status->set(2, j); } } if (abbruch) { // Es sind nicht alle bereit Vorgang abbrechen for (int i = 0; i < spielerAnzahl; i++) { if (status->hat(i) && status->get(i) != 0) { SSKlient* tmp = klients->z(i); if (tmp) tmp->erstellungAbgebrochen((char*)err); } } Array< bool >* inWarteschlange = new Array< bool >(); RCArray< Zeit >* wZeit = new RCArray< Zeit >(); if (ss->zDB()->spielErstelltAbbruch(id, spielerAnzahl, accounts, status, inWarteschlange, wZeit)) // zurück in Warteschlange { for (int i = 0; i < spielerAnzahl; i++) { if (inWarteschlange->hat(i) && inWarteschlange->get(i)) { SSKlient* tmp = klients->z(i); if (tmp) { Zeit* zTmp = wZeit->z(i); if (zTmp) tmp->backInWarteschlange((char)zTmp->zUhrzeit()->getStunde(), (char)zTmp->zUhrzeit()->getMinute(), (char)zTmp->zUhrzeit()->getSekunde()); } } } } inWarteschlange->release(); wZeit->release(); for (int i = 0; i < spielerAnzahl; i++) { SSKlient* tmp = klients->z(i); if (tmp) tmp->trenne(); } zeit->release(); ss->removeSpielErstellt(id); // delete this return; } // alle Spieler sind bereit Vorgang fortsetzen spielId = ss->zDB()->spielErstelltFortsetzen(id); Spiel* weiter = new Spiel(spielId, dynamic_cast(getThis())); ss->addSpiel(weiter); weiter->setAccounts(spielerAnzahl, accounts); weiter->setKlients(spielerAnzahl, klients); weiter->setKarteId(karte); ss->removeSpielErstellt(id); // delete this zeit->release(); } // constant int SpielErstellt::getId() const { return id; } // Inhalt der SpielFinden Klasse aus SpielErstellt.h // Konstruktor SpielFinden::SpielFinden(SpielServer* ss) : Thread() { this->ss = ss; end = 0; spielServerId = 0; } // Destruktor SpielFinden::~SpielFinden() { end = 1; warteAufThread(2000); } // nicht constant void SpielFinden::setEnde() { end = 1; } void SpielFinden::setSpielServerId(int id) { spielServerId = id; } void SpielFinden::thread() { end = 0; while (!end) { for (int i = 0; i < 10 && !end; i++) Sleep(1000); if (end) break; int ret = ss->zDB()->erstelleSpiel(spielServerId); if (!ret) { // erfolg int id = ss->zDB()->getSpielErstelltId(spielServerId); SpielErstellt* erstellt = new SpielErstellt(id, dynamic_cast(getThis())); ss->addSpielErstellt(erstellt); erstellt->sendeVerbindungsBefehl(); ss->zDB()->deleteSpielErstelltNext(spielServerId); } } run = 0; end = 0; }