summaryrefslogtreecommitdiff
path: root/src/network/core/tcp_content.cpp
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2009-01-17 16:53:32 +0000
committerrubidium <rubidium@openttd.org>2009-01-17 16:53:32 +0000
commit3a13b75e37b5642de3c1e89cf6ab3bf860b76375 (patch)
tree76215ba6e27bc0b1f49919c01ff2608f276b8e3d /src/network/core/tcp_content.cpp
parent2850bf9e006ebdd40b5562cca5117bca027cfab5 (diff)
downloadopenttd-3a13b75e37b5642de3c1e89cf6ab3bf860b76375.tar.xz
(svn r15126) -Feature: downloading content from a central server (content.openttd.org) where authors can upload they NewGRFS/AI etc. This should make joining servers that use only NewGRFs that are distributed via this system easier as the players can download the NewGRFs from in the game. It should also make it easier to see whether there are updates for NewGRFs and make the necessary updates.
Diffstat (limited to 'src/network/core/tcp_content.cpp')
-rw-r--r--src/network/core/tcp_content.cpp136
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 */