#include "FactoryClient.h" #include #include #include "Globals.h" using namespace Network; using namespace Framework; FactoryClient::FactoryClient() { client = 0; background = 0; foreground = 0; backgroundReader = 0; foregroundReader = 0; bgReaderUsage = 0; fgReaderUsage = 0; } FactoryClient::~FactoryClient() { if (client) disconnect(); } void FactoryClient::loadServerInfo() { std::cout << "downloading server type information\n"; // receive type information for (int i = 0; i < blockTypeCount; i++) blockTypes[i]->release(); delete[] blockTypes; for (int i = 0; i < itemTypeCount; i++) itemTypes[i]->release(); delete[] itemTypes; for (int i = 0; i < entityTypeCount; i++) entityTypes[i]->release(); delete[] entityTypes; foregroundReader->lese((char*)&blockTypeCount, 4); blockTypes = new BlockType*[blockTypeCount]; for (int i = 0; i < blockTypeCount; i++) { int id; foregroundReader->lese((char*)&id, 4); bool needsInstance; foregroundReader->lese((char*)&needsInstance, 1); bool needsSubscription; foregroundReader->lese((char*)&needsSubscription, 1); bool fluid; foregroundReader->lese((char*)&fluid, 1); char maxFlowDistance = 0; if (fluid) foregroundReader->lese((char*)&maxFlowDistance, 1); int maxHp; foregroundReader->lese((char*)&maxHp, 4); blockTypes[i] = new BlockType(id, needsInstance, ModelInfo(foregroundReader), maxHp, needsSubscription, fluid, maxFlowDistance); } foregroundReader->lese((char*)&itemTypeCount, 4); itemTypes = new ItemType*[itemTypeCount]; for (int i = 0; i < itemTypeCount; i++) { int id; foregroundReader->lese((char*)&id, 4); char len; foregroundReader->lese((char*)&len, 1); char* name = new char[len + 1]; foregroundReader->lese(name, len); name[len] = 0; short tlen; foregroundReader->lese((char*)&tlen, 2); char* tooltipUIML = new char[tlen + 1]; foregroundReader->lese(tooltipUIML, tlen); tooltipUIML[tlen] = 0; itemTypes[i] = new ItemType( id, ModelInfo(foregroundReader), Text(name), Text(tooltipUIML)); delete[] name; delete[] tooltipUIML; } foregroundReader->lese((char*)&entityTypeCount, 4); entityTypes = new EntityType*[entityTypeCount]; for (int i = 0; i < entityTypeCount; i++) { int id; foregroundReader->lese((char*)&id, 4); entityTypes[i] = new EntityType(id, ModelInfo(foregroundReader)); } // pre rendering item models Kam3D* kam = new Kam3D(); Welt3D* w = new Welt3D(); w->addDiffuseLight(DiffuseLight{ Vec3(0.5f, 0.5f, -1.f), Vec3(1.f, 1.f, 1.f)}); kam->setWelt(w); kam->setBildschirmPosition(0, 0); kam->setBildschirmSize(50, 50); kam->setPosition(Vec3(0, 0, 0)); kam->setRotation( {(float)PI / 2.f, 0.f, std::atan2(0.f, -1.f) + (float)PI / 2}); Bild* b = new Bild(); b->neuBild(50, 50, 0); for (int i = 0; i < itemTypeCount; i++) { Model3D* mdl = new Model3D(); Model3DData* data = itemTypes[i]->getItemModel(); if (data) { Vec3 min = data->getMinPos(); Vec3 max = data->getMaxPos(); float maxX = MAX( MAX(MAX(abs(min.x), abs(max.x)), MAX(abs(min.y), abs(max.y))), MAX(abs(min.z), abs(max.z))); kam->setPosition(Vec3(maxX * 3.5f, 0.f, 0.f)); } mdl->setModelDaten(data); mdl->setModelTextur(itemTypes[i]->getItemTextur()); mdl->setPosition(Vec3(0.f, 0.f, 0.f)); mdl->setDrehung(0.25f, 0.25f, 0.55f); mdl->setAmbientFactor(0.8f); mdl->setDiffusFactor(0.1f); mdl->setSpecularFactor(0.1f); mdl->setSize(itemTypes[i]->getSize()); w->addZeichnung(mdl); w->tick(0); window->zBildschirm()->lock(); DX11Textur* t = (DX11Textur*)window->zBildschirm() ->zGraphicsApi() ->createOrGetTextur( Text("rendered/items/") + itemTypes[i]->getId(), dynamic_cast(b->getThis())); window->zBildschirm()->zGraphicsApi()->renderKamera(kam, t); Bild* result = new Bild(); t->copyToImage(result); itemTypes[i]->setBild(result); t->release(); window->zBildschirm()->unlock(); w->removeZeichnung(mdl); } b->release(); kam->release(); } bool FactoryClient::connect(Text ip, unsigned short sslPort) { if (client) disconnect(); client = new SSLKlient(); if (!client->verbinde(sslPort, ip)) return false; char c; while (client->hatNachricht(1)) client->getNachricht(&c, 1); this->ip = ip; return 1; } int FactoryClient::ping() { ZeitMesser zm; zm.messungStart(); if (!client->sende("\3", 1)) return -1; char c; client->getNachricht(&c, 1); zm.messungEnde(); return (int)(zm.getSekunden() * 1000); } int FactoryClient::status(Framework::Text name, Framework::Text secret) { if (!client->sende("\4", 1)) return 404; char c; client->getNachricht(&c, 1); if (c == 1) { char len = (char)name.getLength(); client->sende(&len, 1); client->sende(name, len); short sLen = (short)secret.getLength(); client->sende((char*)&sLen, 2); client->sende(secret, sLen); char res; client->getNachricht(&res, 1); if (res == 1) return 200; if (res == 0) return 403; } return 404; } int FactoryClient::join( Framework::Text name, Framework::Text& secret, unsigned short port) { client->sende("\1", 1); char len = (char)name.getLength(); client->sende(&len, 1); client->sende(name, len); short sLen = (short)secret.getLength(); client->sende((char*)&sLen, 2); client->sende(secret, sLen); char res; client->getNachricht(&res, 1); if (res == 1 || res == 2) { if (res == 2) { client->getNachricht((char*)&sLen, 2); char* buffer = new char[sLen + 1]; client->getNachricht(buffer, sLen); buffer[sLen] = 0; secret = buffer; delete[] buffer; } short keyLen; client->getNachricht((char*)&keyLen, 2); char* key = new char[keyLen]; client->getNachricht(key, keyLen); foreground = new Klient(); if (!foreground->verbinde(port, ip)) { delete[] key; return false; } if (!foreground->sende((char*)&keyLen, 2)) { delete[] key; return false; } if (!foreground->sende(key, keyLen)) { delete[] key; return false; } background = new Klient(); if (!background->verbinde(port, ip)) { delete[] key; foreground->release(); foreground = 0; background->release(); background = 0; return false; } if (!background->sende((char*)&keyLen, 2)) { delete[] key; foreground->release(); foreground = 0; background->release(); background = 0; return false; } if (!background->sende(key, keyLen)) { delete[] key; foreground->release(); foreground = 0; background->release(); background = 0; return false; } delete[] key; bool bg = 0; if (!foreground->sende((char*)&bg, 1)) { delete[] key; return 201; } foregroundReader = new NetworkReader(foreground); bg = 1; if (!background->sende((char*)&bg, 1)) return 201; backgroundReader = new NetworkReader(background); char res; foregroundReader->lese(&res, 1); if (res != 1) return 403; backgroundReader->lese(&res, 1); if (res != 1) return 403; client->trenne(); loadServerInfo(); return 200; } if (res == 0) return 403; return 500; } void FactoryClient::disconnect() { if (client) { NetworkReader* fgReader = foregroundReader; NetworkReader* bgReader = backgroundReader; backgroundReader = 0; foregroundReader = 0; if (foreground) foreground->trenne(); if (background) background->trenne(); while (fgReaderUsage > 0 || bgReaderUsage > 0) Sleep(100); delete fgReader; delete bgReader; client->release(); client = 0; if (foreground) foreground->release(); foreground = 0; if (background) background->release(); background = 0; } } NetworkReader* FactoryClient::getNextForegroundMessage() { fgReaderUsage++; if (!foreground) return 0; if (!foreground->isConnected()) return 0; if (!foreground->hatNachricht(0)) return 0; return foregroundReader; } NetworkReader* FactoryClient::getNextBackgroundMessage() { bgReaderUsage++; if (!background) return 0; if (!background->isConnected()) return 0; if (!background->hatNachricht(0)) return 0; return backgroundReader; } void FactoryClient::endMessageReading(bool bg) { if (bg) bgReaderUsage--; else fgReaderUsage--; } void FactoryClient::sendPlayerAction(const char* data, unsigned short length) { if (!foreground) return; cs.lock(); length += 1; foreground->sende((char*)&length, 2); char msgId = 2; foreground->sende(&msgId, 1); foreground->sende((char*)data, length - 1); cs.unlock(); } void FactoryClient::sendPlayerMovement(MovementFrame& frame) { if (!foreground) return; cs.lock(); short length = 38; foreground->sende((char*)&length, 2); char msgId = 2; // player message foreground->sende(&msgId, 1); foreground->sende(&msgId, 1); // set movement foreground->sende((char*)&frame.direction.x, 4); foreground->sende((char*)&frame.direction.y, 4); foreground->sende((char*)&frame.direction.z, 4); foreground->sende((char*)&frame.targetPosition.x, 4); foreground->sende((char*)&frame.targetPosition.y, 4); foreground->sende((char*)&frame.targetPosition.z, 4); foreground->sende((char*)&frame.movementFlags, 4); foreground->sende((char*)&frame.duration, 8); cs.unlock(); } void FactoryClient::entityAPIRequest( int entityId, const char* message, unsigned short length) { if (!foreground) return; cs.lock(); length += 5; foreground->sende((char*)&length, 2); char msgId = 3; foreground->sende(&msgId, 1); foreground->sende((char*)&entityId, 4); foreground->sende(message, length - 5); cs.unlock(); } void FactoryClient::blockAPIRequest( Vec3 pos, const char* message, unsigned short length) { if (!foreground) return; cs.lock(); length += 14; foreground->sende((char*)&length, 2); char msgId = 1; foreground->sende(&msgId, 1); foreground->sende(&msgId, 1); foreground->sende((char*)&pos.x, 4); foreground->sende((char*)&pos.y, 4); foreground->sende((char*)&pos.z, 4); foreground->sende(message, length - 14); cs.unlock(); } void FactoryClient::blockAPIRequest( int dimensionId, Vec3 pos, const char* message, unsigned short length) { if (!foreground) return; cs.lock(); length += 18; foreground->sende((char*)&length, 2); char msgId = 7; foreground->sende(&msgId, 1); foreground->sende((char*)&dimensionId, 4); msgId = 1; foreground->sende(&msgId, 1); foreground->sende((char*)&pos.x, 4); foreground->sende((char*)&pos.y, 4); foreground->sende((char*)&pos.z, 4); foreground->sende(message, length - 18); cs.unlock(); } void FactoryClient::chunkAPIRequest( Punkt center, const char* message, unsigned short length) { if (!foreground) return; length += 10; cs.lock(); foreground->sende((char*)&length, 2); char type = 1; foreground->sende(&type, 1); type = 0; foreground->sende(&type, 1); foreground->sende((char*)¢er.x, 4); foreground->sende((char*)¢er.y, 4); foreground->sende(message, length - 10); cs.unlock(); } void FactoryClient::dimensionAPIRequest( const char* message, unsigned short length) { if (!foreground) return; length += 1; cs.lock(); foreground->sende((char*)&length, 2); char type = 1; foreground->sende(&type, 1); foreground->sende(message, length - 1); cs.unlock(); } void FactoryClient::inventoryAPIRequest( Framework::Either> target, const char* message, unsigned short length) { if (!foreground) return; cs.lock(); length += target.isA() ? 6 : 18; foreground->sende((char*)&length, 2); char msgId = 4; foreground->sende(&msgId, 1); bool isEntity = target.isA(); foreground->sende((char*)&isEntity, 1); if (target.isA()) { int id = target.getA(); foreground->sende((char*)&id, 4); } else { for (int i = 0; i < 4; i++) { int v = target.getB()[i]; foreground->sende((char*)&v, 4); } } foreground->sende(message, length - (target.isA() ? 6 : 18)); cs.unlock(); } void FactoryClient::uiRequest( Framework::Text dialogId, const char* message, unsigned short length) { if (!foreground) return; short nameLen = (short)dialogId.getLength(); length += nameLen + 3; foreground->sende((char*)&length, 2); cs.lock(); char msgId = 8; foreground->sende(&msgId, 1); foreground->sende((char*)&nameLen, 2); foreground->sende(dialogId, nameLen); foreground->sende(message, length - nameLen - 3); cs.unlock(); } void FactoryClient::craftingUIMLRequest(int itemTypeId) { if (!foreground) return; cs.lock(); short length = 5; foreground->sende((char*)&length, 2); char msgId = 5; foreground->sende(&msgId, 1); foreground->sende((char*)&itemTypeId, 4); cs.unlock(); } void FactoryClient::sendChatMessage(Framework::Text message) { if (!background) return; cs.lock(); short length = message.getLength() + 4; background->sende((char*)&length, 2); char msgId = 6; background->sende(&msgId, 1); msgId = 0; background->sende(&msgId, 1); length = message.getLength(); background->sende((char*)&length, 2); background->sende(message.getText(), message.getLength()); cs.unlock(); } void FactoryClient::chatAPIRequest(const char* data, unsigned short length) { if (!background) return; cs.lock(); short totalLength = length + 1; background->sende((char*)&totalLength, 2); char msgId = 6; background->sende(&msgId, 1); background->sende(data, length); cs.unlock(); } bool FactoryClient::isConnected() { return foreground && background && foreground->isConnected() && background->isConnected(); } void FactoryClient::leaveGame() { cs.lock(); disconnect(); cs.unlock(); }