#include "GameClient.h" #include #include "Constants.h" #include "Dimension.h" #include "Game.h" #include "Player.h" #include "Server.h" GameClient::GameClient(Player* zPlayer, FCKlient* client) : Thread(), zPlayer(zPlayer), client(client), viewDistance(DEFAULT_VIEW_DISTANCE), first(1), online(1), finished(0), backgroundFinished(0), foregroundFinished(0) { start(); } GameClient::~GameClient() { online = 0; emptyForegroundQueueSync.notifyAll(); emptyBackgroundQueueSync.notifyAll(); foregroundQueueSync.notify(); backgroundQueueSync.notify(); while (!finished || !foregroundFinished || !backgroundFinished) Sleep(100); client->release(); } void GameClient::thread() { new AsynchronCall("Game Client Background", [this]() { while (online) { queueCs.lock(); if (backgroundQueue.hat(0)) { NetworkMessage* message = backgroundQueue.get(0); backgroundQueue.remove(0); queueCs.unlock(); background.lock(); message->writeTo(client->zBackgroundWriter()); background.unlock(); message->release(); } else { queueCs.unlock(); emptyBackgroundQueueSync.notifyAll(); while (!backgroundQueueSync.wait(1000)) { emptyBackgroundQueueSync.notifyAll(); } } } backgroundFinished = 1; }); while (online) { queueCs.lock(); if (foregroundQueue.hat(0)) { NetworkMessage* message = foregroundQueue.get(0); foregroundQueue.remove(0); queueCs.unlock(); foreground.lock(); message->writeTo(client->zForegroundWriter()); foreground.unlock(); message->release(); } else { queueCs.unlock(); emptyForegroundQueueSync.notifyAll(); while (!foregroundQueueSync.wait(1000)) { emptyForegroundQueueSync.notifyAll(); } } } foregroundFinished = 1; } void GameClient::reply() { other.lock(); for (auto req : requests) Game::INSTANCE->api(req, this); requests.leeren(); other.unlock(); if (first) { foreground.lock(); int id = zPlayer->getId(); client->zForegroundWriter()->schreibe( (char*)&Message::POSITION_UPDATE, 1); client->zForegroundWriter()->schreibe((char*)&id, 4); id = zPlayer->getDimensionId(); client->zForegroundWriter()->schreibe((char*)&id, 4); client->zForegroundWriter()->schreibe((char*)&Message::API_MESSAGE, 1); int len = 10; client->zForegroundWriter()->schreibe((char*)&len, 4); client->zForegroundWriter()->schreibe("\1", 1); client->zForegroundWriter()->schreibe((char*)&id, 4); client->zForegroundWriter()->schreibe("\6", 1); float gravity = Game::INSTANCE->zDimension(zPlayer->getDimensionId()) ->getGravity(); client->zForegroundWriter()->schreibe((char*)&gravity, 4); foreground.unlock(); first = 0; } } void GameClient::logout() { online = 0; emptyForegroundQueueSync.notifyAll(); emptyBackgroundQueueSync.notifyAll(); foregroundQueueSync.notify(); backgroundQueueSync.notify(); } void GameClient::addMessage(StreamReader* reader) { short len = 0; reader->lese((char*)&len, 2); InMemoryBuffer* buffer = new InMemoryBuffer(); char* tmp = new char[len]; reader->lese(tmp, len); buffer->schreibe(tmp, len); delete[] tmp; other.lock(); requests.add(buffer); other.unlock(); } bool GameClient::isOnline() const { return online; } void GameClient::sendResponse(NetworkMessage* response) { queueCs.lock(); if (response->isUseBackground()) { if (backgroundQueue.getEintragAnzahl() > 20) { queueCs.unlock(); while (!emptyBackgroundQueueSync.wait(1000)) { backgroundQueueSync.notify(); } queueCs.lock(); } backgroundQueue.add(response); queueCs.unlock(); backgroundQueueSync.notify(); } else { if (foregroundQueue.getEintragAnzahl() > 100) { queueCs.unlock(); Framework::Logging::warning() << "Game paused because nework connection to " << zPlayer->getName() << " is to slow."; ZeitMesser m; m.messungStart(); while (foregroundQueue.getEintragAnzahl() > 0) { foregroundQueueSync.notify(); emptyForegroundQueueSync.wait(100); } m.messungEnde(); Framework::Logging::warning() << "Game resumed after " << m.getSekunden() << " seconds."; queueCs.lock(); } foregroundQueue.add(response); queueCs.unlock(); foregroundQueueSync.notify(); } } Player* GameClient::zEntity() const { return zPlayer; } void GameClient::sendTypes() { foreground.lock(); int count = 0; for (int i = 0; i < Game::INSTANCE->getBlockTypeCount(); i++) { if (Game::INSTANCE->zBlockType(i)) count++; } client->zForegroundWriter()->schreibe((char*)&count, 4); for (int i = 0; i < Game::INSTANCE->getBlockTypeCount(); i++) { const BlockType* t = Game::INSTANCE->zBlockType(i); if (t) { t->writeTypeInfo(client->zForegroundWriter()); } } count = 0; for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++) { if (Game::INSTANCE->zItemType(i)) count++; } client->zForegroundWriter()->schreibe((char*)&count, 4); for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++) { const ItemType* t = Game::INSTANCE->zItemType(i); if (t) { int id = t->getId(); client->zForegroundWriter()->schreibe((char*)&id, 4); char len = (char)t->getName().getLength(); client->zForegroundWriter()->schreibe((char*)&len, 1); client->zForegroundWriter()->schreibe(t->getName().getText(), len); short tlen = (short)t->getTooltipUIML().getLength(); client->zForegroundWriter()->schreibe((char*)&tlen, 2); client->zForegroundWriter()->schreibe( t->getTooltipUIML().getText(), tlen); if (t->zModel()) { t->zModel()->writeTo(client->zForegroundWriter()); } else { ModelInfo("", Framework::RCArray(), false, 1.f) .writeTo(client->zForegroundWriter()); } } } count = 0; for (int i = 0; i < Game::INSTANCE->getEntityTypeCount(); i++) { if (Game::INSTANCE->zEntityType(i)) count++; } client->zForegroundWriter()->schreibe((char*)&count, 4); for (int i = 0; i < count; i++) { const EntityType* t = Game::INSTANCE->zEntityType(i); int id = t->getId(); client->zForegroundWriter()->schreibe((char*)&id, 4); if (t->zModel()) { t->zModel()->writeTo(client->zForegroundWriter()); } else { ModelInfo("", Framework::RCArray(), false, 1.f) .writeTo(client->zForegroundWriter()); } } foreground.unlock(); }