#include #include #include "FactoryClient.h" #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() { // 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); int maxHp; foregroundReader->lese((char*)&maxHp, 4); blockTypes[i] = new BlockType(id, needsInstance, ModelInfo(foregroundReader), maxHp); } foregroundReader->lese((char*)&itemTypeCount, 4); itemTypes = new ItemType * [itemTypeCount]; for (int i = 0; i < itemTypeCount; i++) { int id; foregroundReader->lese((char*)&id, 4); itemTypes[i] = new ItemType(id, ModelInfo(foregroundReader)); } 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({ 2.f, 0, -1.f }); Bild* b = new Bild(); b->neuBild(50, 50, 0); for (int i = 0; i < itemTypeCount; i++) { Model3D* mdl = new Model3D(); mdl->setModelDaten(itemTypes[i]->getItemModel()); mdl->setModelTextur(itemTypes[i]->getItemTextur()); mdl->setPosition(Vec3(-0.8f, -0.45f, -0.4f)); mdl->setSize(2.f); w->addZeichnung(mdl); w->tick(0); window->zBildschirm()->lock(); DX11Textur* t = (DX11Textur*)window->zBildschirm()->zGraphicsApi()->createOrGetTextur(Text("rendered/items/") + i, dynamic_cast(b->getThis())); window->zBildschirm()->zGraphicsApi()->renderKamera(kam, t); Bild* result = new Bild(); t->copyToImage(result); itemIcons->add(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; 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; } int keyLen; client->getNachricht((char*)&keyLen, 4); 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); 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->hatNachricht(0)) return 0; return foregroundReader; } NetworkReader* FactoryClient::getNextBackgroundMessage() { bgReaderUsage++; if (!background) return 0; if (!background->hatNachricht(0)) return 0; return backgroundReader; } void FactoryClient::endMessageReading(bool bg) { if (bg) bgReaderUsage--; else fgReaderUsage--; } void FactoryClient::sendPlayerAction(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, 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::chunkAPIRequest(Punkt center, char* message, unsigned short length) { 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::inventoryAPIRequest(Framework::Either> target, 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(); }