diff options
Diffstat (limited to 'src/network/core/tcp_content.cpp')
-rw-r--r-- | src/network/core/tcp_content.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/src/network/core/tcp_content.cpp b/src/network/core/tcp_content.cpp new file mode 100644 index 000000000..32054a1e2 --- /dev/null +++ b/src/network/core/tcp_content.cpp @@ -0,0 +1,136 @@ +/* $Id$ */ + +/** + * @file tcp_content.cpp Basic functions to receive and send Content packets. + */ + +#ifdef ENABLE_NETWORK + +#include "../../stdafx.h" +#include "../../debug.h" +#include "tcp_content.h" + +ContentInfo::ContentInfo() +{ + memset(this, 0, sizeof(*this)); +} + +ContentInfo::~ContentInfo() +{ + free(this->dependencies); + free(this->tags); +} + +size_t ContentInfo::Size() const +{ + size_t len = 0; + for (uint i = 0; i < this->tag_count; i++) len += strlen(this->tags[i]) + 1; + + /* The size is never larger than the content info size plus the size of the + * tags and dependencies */ + return sizeof(*this) + + sizeof(this->dependency_count) + + sizeof(*this->dependencies) * this->dependency_count; +} + +bool ContentInfo::IsSelected() const +{ + switch (this->state) { + case ContentInfo::SELECTED: + case ContentInfo::AUTOSELECTED: + return true; + + default: + return false; + } +} + +bool ContentInfo::IsValid() const +{ + return this->state < ContentInfo::INVALID && this->type >= CONTENT_TYPE_BEGIN && this->type < CONTENT_TYPE_END; +} + +NetworkRecvStatus NetworkContentSocketHandler::CloseConnection() +{ + this->has_quit = true; + return NETWORK_RECV_STATUS_OKAY; +} + +void NetworkContentSocketHandler::Close() +{ + CloseConnection(); + if (this->sock == INVALID_SOCKET) return; + + closesocket(this->sock); + this->sock = INVALID_SOCKET; +} + +/** + * Defines a simple (switch) case for each network packet + * @param type the packet type to create the case for + */ +#define CONTENT_COMMAND(type) case type: return this->NetworkPacketReceive_ ## type ## _command(p); break; + +/** + * Handle an incoming packets by sending it to the correct function. + * @param p the received packet + */ +bool NetworkContentSocketHandler::HandlePacket(Packet *p) +{ + PacketContentType type = (PacketContentType)p->Recv_uint8(); + + switch (this->HasClientQuit() ? PACKET_CONTENT_END : type) { + CONTENT_COMMAND(PACKET_CONTENT_CLIENT_INFO_LIST); + CONTENT_COMMAND(PACKET_CONTENT_CLIENT_INFO_ID); + CONTENT_COMMAND(PACKET_CONTENT_CLIENT_INFO_EXTID); + CONTENT_COMMAND(PACKET_CONTENT_CLIENT_INFO_EXTID_MD5); + CONTENT_COMMAND(PACKET_CONTENT_SERVER_INFO); + CONTENT_COMMAND(PACKET_CONTENT_CLIENT_CONTENT); + CONTENT_COMMAND(PACKET_CONTENT_SERVER_CONTENT); + + default: + if (this->HasClientQuit()) { + DEBUG(net, 0, "[tcp/content] received invalid packet type %d from %s:%d", type, inet_ntoa(this->client_addr.sin_addr), ntohs(this->client_addr.sin_port)); + } else { + DEBUG(net, 0, "[tcp/content] received illegal packet from %s:%d", inet_ntoa(this->client_addr.sin_addr), ntohs(this->client_addr.sin_port)); + } + return false; + } +} + +/** + * Receive a packet at UDP level + */ +void NetworkContentSocketHandler::Recv_Packets() +{ + Packet *p; + NetworkRecvStatus res; + while ((p = this->Recv_Packet(&res)) != NULL) { + bool cont = HandlePacket(p); + delete p; + if (!cont) return; + } +} + +/** + * Create stub implementations for all receive commands that only + * show a warning that the given command is not available for the + * socket where the packet came from. + * @param type the packet type to create the stub for + */ +#define DEFINE_UNAVAILABLE_CONTENT_RECEIVE_COMMAND(type) \ +bool NetworkContentSocketHandler::NetworkPacketReceive_## type ##_command(Packet *p) { \ + DEBUG(net, 0, "[tcp/content] received illegal packet type %d from %s:%d", \ + type, inet_ntoa(this->client_addr.sin_addr), ntohs(this->client_addr.sin_port)); \ + return false; \ +} + +DEFINE_UNAVAILABLE_CONTENT_RECEIVE_COMMAND(PACKET_CONTENT_CLIENT_INFO_LIST); +DEFINE_UNAVAILABLE_CONTENT_RECEIVE_COMMAND(PACKET_CONTENT_CLIENT_INFO_ID); +DEFINE_UNAVAILABLE_CONTENT_RECEIVE_COMMAND(PACKET_CONTENT_CLIENT_INFO_EXTID); +DEFINE_UNAVAILABLE_CONTENT_RECEIVE_COMMAND(PACKET_CONTENT_CLIENT_INFO_EXTID_MD5); +DEFINE_UNAVAILABLE_CONTENT_RECEIVE_COMMAND(PACKET_CONTENT_SERVER_INFO); +DEFINE_UNAVAILABLE_CONTENT_RECEIVE_COMMAND(PACKET_CONTENT_CLIENT_CONTENT); +DEFINE_UNAVAILABLE_CONTENT_RECEIVE_COMMAND(PACKET_CONTENT_SERVER_CONTENT); + +#endif /* ENABLE_NETWORK */ |