Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00014 #ifdef ENABLE_NETWORK
00015
00016 #include "../../stdafx.h"
00017 #include "../../textfile_gui.h"
00018 #include "../../fileio_func.h"
00019 #include "../../newgrf_config.h"
00020 #include "../../base_media_base.h"
00021 #include "../../ai/ai.hpp"
00022 #include "../../game/game.hpp"
00023 #include "../../fios.h"
00024 #include "tcp_content.h"
00025
00027 ContentInfo::ContentInfo()
00028 {
00029 memset(this, 0, sizeof(*this));
00030 }
00031
00033 ContentInfo::~ContentInfo()
00034 {
00035 free(this->dependencies);
00036 free(this->tags);
00037 }
00038
00043 void ContentInfo::TransferFrom(ContentInfo *other)
00044 {
00045 if (other != this) {
00046 free(this->dependencies);
00047 free(this->tags);
00048 memcpy(this, other, sizeof(ContentInfo));
00049 other->dependencies = NULL;
00050 other->tags = NULL;
00051 }
00052 }
00053
00058 size_t ContentInfo::Size() const
00059 {
00060 size_t len = 0;
00061 for (uint i = 0; i < this->tag_count; i++) len += strlen(this->tags[i]) + 1;
00062
00063
00064
00065 return sizeof(*this) +
00066 sizeof(this->dependency_count) +
00067 sizeof(*this->dependencies) * this->dependency_count;
00068 }
00069
00074 bool ContentInfo::IsSelected() const
00075 {
00076 switch (this->state) {
00077 case ContentInfo::SELECTED:
00078 case ContentInfo::AUTOSELECTED:
00079 case ContentInfo::ALREADY_HERE:
00080 return true;
00081
00082 default:
00083 return false;
00084 }
00085 }
00086
00091 bool ContentInfo::IsValid() const
00092 {
00093 return this->state < ContentInfo::INVALID && this->type >= CONTENT_TYPE_BEGIN && this->type < CONTENT_TYPE_END;
00094 }
00095
00101 const char *ContentInfo::GetTextfile(TextfileType type) const
00102 {
00103 if (this->state == INVALID) return NULL;
00104 const char *tmp;
00105 switch (this->type) {
00106 default: NOT_REACHED();
00107 case CONTENT_TYPE_AI:
00108 tmp = AI::GetScannerInfo()->FindMainScript(this, true);
00109 break;
00110 case CONTENT_TYPE_AI_LIBRARY:
00111 tmp = AI::GetScannerLibrary()->FindMainScript(this, true);
00112 break;
00113 case CONTENT_TYPE_GAME:
00114 tmp = Game::GetScannerInfo()->FindMainScript(this, true);
00115 break;
00116 case CONTENT_TYPE_GAME_LIBRARY:
00117 tmp = Game::GetScannerLibrary()->FindMainScript(this, true);
00118 break;
00119 case CONTENT_TYPE_NEWGRF:
00120 tmp = FindGRFConfig(BSWAP32(this->unique_id), FGCM_EXACT, this->md5sum)->filename;
00121 break;
00122 case CONTENT_TYPE_BASE_GRAPHICS:
00123 tmp = TryGetBaseSetFile(this, true, BaseGraphics::GetAvailableSets());
00124 break;
00125 case CONTENT_TYPE_BASE_SOUNDS:
00126 tmp = TryGetBaseSetFile(this, true, BaseSounds::GetAvailableSets());
00127 break;
00128 case CONTENT_TYPE_BASE_MUSIC:
00129 tmp = TryGetBaseSetFile(this, true, BaseMusic::GetAvailableSets());
00130 break;
00131 case CONTENT_TYPE_SCENARIO:
00132 case CONTENT_TYPE_HEIGHTMAP:
00133 extern const char *FindScenario(const ContentInfo *ci, bool md5sum);
00134 tmp = FindScenario(this, true);
00135 break;
00136 }
00137 if (tmp == NULL) return NULL;
00138 return ::GetTextfile(type, GetContentInfoSubDir(this->type), tmp);
00139 }
00140
00141 void NetworkContentSocketHandler::Close()
00142 {
00143 CloseConnection();
00144 if (this->sock == INVALID_SOCKET) return;
00145
00146 closesocket(this->sock);
00147 this->sock = INVALID_SOCKET;
00148 }
00149
00154 #define CONTENT_COMMAND(type) case type: return this->NetworkPacketReceive_ ## type ## _command(p); break;
00155
00162 bool NetworkContentSocketHandler::HandlePacket(Packet *p)
00163 {
00164 PacketContentType type = (PacketContentType)p->Recv_uint8();
00165
00166 switch (this->HasClientQuit() ? PACKET_CONTENT_END : type) {
00167 case PACKET_CONTENT_CLIENT_INFO_LIST: return this->Receive_CLIENT_INFO_LIST(p);
00168 case PACKET_CONTENT_CLIENT_INFO_ID: return this->Receive_CLIENT_INFO_ID(p);
00169 case PACKET_CONTENT_CLIENT_INFO_EXTID: return this->Receive_CLIENT_INFO_EXTID(p);
00170 case PACKET_CONTENT_CLIENT_INFO_EXTID_MD5: return this->Receive_CLIENT_INFO_EXTID_MD5(p);
00171 case PACKET_CONTENT_SERVER_INFO: return this->Receive_SERVER_INFO(p);
00172 case PACKET_CONTENT_CLIENT_CONTENT: return this->Receive_CLIENT_CONTENT(p);
00173 case PACKET_CONTENT_SERVER_CONTENT: return this->Receive_SERVER_CONTENT(p);
00174
00175 default:
00176 if (this->HasClientQuit()) {
00177 DEBUG(net, 0, "[tcp/content] received invalid packet type %d from %s", type, this->client_addr.GetAddressAsString());
00178 } else {
00179 DEBUG(net, 0, "[tcp/content] received illegal packet from %s", this->client_addr.GetAddressAsString());
00180 }
00181 return false;
00182 }
00183 }
00184
00188 void NetworkContentSocketHandler::ReceivePackets()
00189 {
00190 Packet *p;
00191 while ((p = this->ReceivePacket()) != NULL) {
00192 bool cont = this->HandlePacket(p);
00193 delete p;
00194 if (!cont) return;
00195 }
00196 }
00197
00198
00204 bool NetworkContentSocketHandler::ReceiveInvalidPacket(PacketContentType type)
00205 {
00206 DEBUG(net, 0, "[tcp/content] received illegal packet type %d from %s", type, this->client_addr.GetAddressAsString());
00207 return false;
00208 }
00209
00210 bool NetworkContentSocketHandler::Receive_CLIENT_INFO_LIST(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_LIST); }
00211 bool NetworkContentSocketHandler::Receive_CLIENT_INFO_ID(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_ID); }
00212 bool NetworkContentSocketHandler::Receive_CLIENT_INFO_EXTID(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_EXTID); }
00213 bool NetworkContentSocketHandler::Receive_CLIENT_INFO_EXTID_MD5(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_EXTID_MD5); }
00214 bool NetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_SERVER_INFO); }
00215 bool NetworkContentSocketHandler::Receive_CLIENT_CONTENT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_CONTENT); }
00216 bool NetworkContentSocketHandler::Receive_SERVER_CONTENT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_SERVER_CONTENT); }
00217
00223 Subdirectory GetContentInfoSubDir(ContentType type)
00224 {
00225 switch (type) {
00226 default: return NO_DIRECTORY;
00227 case CONTENT_TYPE_AI: return AI_DIR;
00228 case CONTENT_TYPE_AI_LIBRARY: return AI_LIBRARY_DIR;
00229 case CONTENT_TYPE_GAME: return GAME_DIR;
00230 case CONTENT_TYPE_GAME_LIBRARY: return GAME_LIBRARY_DIR;
00231 case CONTENT_TYPE_NEWGRF: return NEWGRF_DIR;
00232
00233 case CONTENT_TYPE_BASE_GRAPHICS:
00234 case CONTENT_TYPE_BASE_SOUNDS:
00235 case CONTENT_TYPE_BASE_MUSIC:
00236 return BASESET_DIR;
00237
00238 case CONTENT_TYPE_SCENARIO:
00239 case CONTENT_TYPE_HEIGHTMAP:
00240 return SCENARIO_DIR;
00241 }
00242 }
00243
00244 #endif