#include "NetworkMessage.h" #include #include "ChatMessage.h" #include "ChatObserver.h" #include "Chunk.h" #include "ChunkMap.h" #include "Dimension.h" #include "Entity.h" #include "EntityType.h" #include "Game.h" NetworkMessage::NetworkMessage() : Framework::ReferenceCounter(), onAfterSend(0) { address = 0; addressLength = 0; broadcast = 0; message = 0; msgLength = 0; useBackground = 0; } NetworkMessage::~NetworkMessage() { delete[] message; delete[] address; } void NetworkMessage::setOnAfterSend(std::function onAfterSend) { if (this->onAfterSend) throw "Illegal State exception: onAfterSend was already set"; this->onAfterSend = onAfterSend; } void NetworkMessage::addressChunck(const Chunk* zChunk) { delete[] address; addressLength = 14; address = new char[addressLength]; address[0] = 1; // dimension response *(int*)(address + 1) = zChunk->getDimensionId(); address[5] = 1; // chunck Framework::Punkt center = zChunk->getCenter(); *(int*)(address + 6) = center.x; *(int*)(address + 10) = center.y; } void NetworkMessage::addressEntity(const Entity* zEntity) { delete[] address; addressLength = 10; address = new char[addressLength]; address[0] = 1; // dimension response *(int*)(address + 1) = zEntity->getDimensionId(); address[5] = 2; // entity *(int*)(address + 6) = zEntity->getId(); } void NetworkMessage::addressDimension(const Dimension* zDim) { delete[] address; addressLength = 5; address = new char[5]; address[0] = 1; // dimension response *(int*)(address + 1) = zDim->getDimensionId(); } void NetworkMessage::addressBlock(const Block* zBlock) { delete[] address; addressLength = 18; address = new char[addressLength]; address[0] = 1; // dimension response *(int*)(address + 1) = zBlock->getDimensionId(); address[5] = 3; // block Framework::Vec3 pos = zBlock->getPos(); *(int*)(address + 6) = pos.x; *(int*)(address + 10) = pos.y; *(int*)(address + 14) = pos.z; } void NetworkMessage::openDialog( Framework::Text dialogName, Framework::Text uiml) { delete[] address; addressLength = (char)(4 + dialogName.getLength()); address = new char[addressLength]; address[0] = 2; // gui message address[1] = 0; // open dialog *(short*)(address + 2) = (short)dialogName.getLength(); // block memcpy(address + 4, dialogName.getText(), dialogName.getLength()); int msgSize = 4 + uiml.getLength(); char* msg = new char[msgSize]; *(int*)msg = uiml.getLength(); memcpy(msg + 4, uiml.getText(), uiml.getLength()); setMessage(msg, msgSize); } void NetworkMessage::updateDialog( Framework::Text dialogName, Framework::Text uiml) { delete[] address; addressLength = (char)(4 + dialogName.getLength()); address = new char[addressLength]; address[0] = 2; // gui message address[1] = 3; // update dialog *(short*)(address + 2) = (short)dialogName.getLength(); // dialog name memcpy(address + 4, dialogName.getText(), dialogName.getLength()); int msgSize = 4 + uiml.getLength(); char* msg = new char[msgSize]; *(int*)msg = uiml.getLength(); memcpy(msg + 4, uiml.getText(), uiml.getLength()); setMessage(msg, msgSize); } void NetworkMessage::addressUIElement(Framework::Text elementId) { delete[] address; addressLength = (char)(4 + elementId.getLength()); address = new char[addressLength]; address[0] = 2; // gui message address[1] = 1; // element message *(short*)(address + 2) = (short)elementId.getLength(); // element id memcpy(address + 4, elementId.getText(), elementId.getLength()); } void NetworkMessage::setMessage(char* msg, int length) { delete[] message; message = msg; msgLength = length; } void NetworkMessage::sendChatMessage(ChatMessage* zMsg) { delete[] address; addressLength = 1; address = new char[1]; address[0] = 4; // chat message Framework::InMemoryBuffer buffer; zMsg->writeTo(&buffer); char* msg = new char[buffer.getSize()]; buffer.lese(msg, (int)buffer.getSize()); setMessage(msg, (int)buffer.getSize()); } void NetworkMessage::sendChatOptions(ChatObserver* zOptions) { delete[] address; addressLength = 1; address = new char[1]; address[0] = 5; // chat options Framework::InMemoryBuffer buffer; zOptions->writeTo(&buffer); char* msg = new char[buffer.getSize()]; buffer.lese(msg, (int)buffer.getSize()); setMessage(msg, (int)buffer.getSize()); } void NetworkMessage::sendMap(ChunkMap* zMap) { delete[] address; addressLength = 1; address = new char[1]; address[0] = 6; // map data Framework::InMemoryBuffer buffer; zMap->writeTo(&buffer); char* msg = new char[buffer.getSize()]; buffer.lese(msg, (int)buffer.getSize()); setMessage(msg, (int)buffer.getSize()); } void NetworkMessage::sendPlayerPositions(char* msg, int length) { delete[] address; addressLength = 1; address = new char[1]; address[0] = 7; // map player positions setMessage(msg, length); } void NetworkMessage::setUseBackground() { useBackground = 1; } void NetworkMessage::sendToAll() { broadcast = true; } void NetworkMessage::animateBlockBone(int dimensionId, Framework::Punkt chunkCenter, int index, int boneId, double time, Framework::Vec3 pos, Framework::Vec3 rotation) { delete[] address; addressLength = 15; address = new char[addressLength]; address[0] = 1; // dimension api *(int*)(address + 1) = dimensionId; address[5] = 1; // chunk api *(int*)(address + 6) = chunkCenter.x; *(int*)(address + 10) = chunkCenter.y; address[14] = 1; // animate block char* msg = new char[40]; *(int*)(msg) = index; *(int*)(msg + 4) = boneId; *(double*)(msg + 8) = time; *(float*)(msg + 16) = pos.x; *(float*)(msg + 20) = pos.y; *(float*)(msg + 24) = pos.z; *(float*)(msg + 28) = rotation.x; *(float*)(msg + 32) = rotation.y; *(float*)(msg + 36) = rotation.z; setMessage(msg, 40); } void NetworkMessage::syncTime( double time, double nightLength, double transitionLength, double dayLength) { delete[] address; addressLength = 1; address = new char[1]; address[0] = 8; delete[] message; msgLength = 8 * 4; message = new char[msgLength]; *(double*)(message) = time; *(double*)(message + 8) = nightLength; *(double*)(message + 16) = transitionLength; *(double*)(message + 24) = dayLength; } void NetworkMessage::addEntityMessage(const Entity* zEntity) { Dimension* dim = Game::INSTANCE->zDimension(zEntity->getDimensionId()); if (dim) { addressDimension(dim); Framework::InMemoryBuffer buffer; int id = zEntity->zType()->getId(); buffer.schreibe("\x7", 1); // add entity buffer.schreibe((char*)&id, 4); id = zEntity->getId(); buffer.schreibe((char*)&id, 4); Framework::Vec3 pos = zEntity->getPosition(); buffer.schreibe((char*)&pos.x, 4); buffer.schreibe((char*)&pos.y, 4); buffer.schreibe((char*)&pos.z, 4); float maxSpeed = zEntity->getMaxSpeed(); buffer.schreibe((char*)&maxSpeed, 4); float gravityMultiplier = zEntity->getGravityMultiplier(); buffer.schreibe((char*)&gravityMultiplier, 4); float jumpSpeed = zEntity->getJumpSpeed(); buffer.schreibe((char*)&jumpSpeed, 4); bool special = !zEntity->hasDefaultModel(); buffer.schreibe((char*)&special, 1); if (special) zEntity->zSpecialModel()->writeTo(&buffer); msgLength = (int)buffer.getSize(); message = new char[msgLength]; buffer.lese(message, (int)buffer.getSize()); } } void NetworkMessage::removeEntityMessage(const Entity* zEntity) { Dimension* dim = Game::INSTANCE->zDimension(zEntity->getDimensionId()); if (dim) { addressDimension(dim); msgLength = 5; message = new char[5]; message[0] = '\x8'; *(int*)(message + 1) = zEntity->getId(); } } void NetworkMessage::writeTo(Framework::StreamWriter* zWriter) const { int total = msgLength + addressLength; if (total > 0) { zWriter->schreibe((char*)&GameClient::Message::API_MESSAGE, 1); zWriter->schreibe((char*)&total, 4); zWriter->schreibe(address, addressLength); zWriter->schreibe(message, msgLength); if (onAfterSend) onAfterSend(); } else { Framework::Logging::error() << "invalid message was queued"; } } bool NetworkMessage::isBroadcast() const { return broadcast; } bool NetworkMessage::isEmpty() const { return msgLength + addressLength <= 0; } bool NetworkMessage::isUseBackground() const { return useBackground; } NetworkMessage* NetworkMessage::clone() const { NetworkMessage* result = new NetworkMessage(); result->message = new char[(int)msgLength]; memcpy(result->message, message, (int)msgLength); result->msgLength = msgLength; result->address = new char[(int)addressLength]; memcpy(result->address, address, (int)addressLength); result->addressLength = addressLength; result->broadcast = broadcast; result->useBackground = useBackground; return result; }