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 #ifndef OPENTTD_MSU
00018 #include "../../textfile_gui.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 #endif
00025 #include "tcp_content.h"
00026
00028 ContentInfo::ContentInfo()
00029 {
00030 memset(this, 0, sizeof(*this));
00031 }
00032
00034 ContentInfo::~ContentInfo()
00035 {
00036 free(this->dependencies);
00037 free(this->tags);
00038 }
00039
00044 void ContentInfo::TransferFrom(ContentInfo *other)
00045 {
00046 if (other != this) {
00047 free(this->dependencies);
00048 free(this->tags);
00049 memcpy(this, other, sizeof(ContentInfo));
00050 other->dependencies = NULL;
00051 other->tags = NULL;
00052 }
00053 }
00054
00059 size_t ContentInfo::Size() const
00060 {
00061 size_t len = 0;
00062 for (uint i = 0; i < this->tag_count; i++) len += strlen(this->tags[i]) + 1;
00063
00064
00065
00066 return sizeof(*this) +
00067 sizeof(this->dependency_count) +
00068 sizeof(*this->dependencies) * this->dependency_count;
00069 }
00070
00075 bool ContentInfo::IsSelected() const
00076 {
00077 switch (this->state) {
00078 case ContentInfo::SELECTED:
00079 case ContentInfo::AUTOSELECTED:
00080 case ContentInfo::ALREADY_HERE:
00081 return true;
00082
00083 default:
00084 return false;
00085 }
00086 }
00087
00092 bool ContentInfo::IsValid() const
00093 {
00094 return this->state < ContentInfo::INVALID && this->type >= CONTENT_TYPE_BEGIN && this->type < CONTENT_TYPE_END;
00095 }
00096
00097 #ifndef OPENTTD_MSU
00098
00103 const char *ContentInfo::GetTextfile(TextfileType type) const
00104 {
00105 if (this->state == INVALID) return NULL;
00106 const char *tmp;
00107 switch (this->type) {
00108 default: NOT_REACHED();
00109 case CONTENT_TYPE_AI:
00110 tmp = AI::GetScannerInfo()->FindMainScript(this, true);
00111 break;
00112 case CONTENT_TYPE_AI_LIBRARY:
00113 tmp = AI::GetScannerLibrary()->FindMainScript(this, true);
00114 break;
00115 case CONTENT_TYPE_GAME:
00116 tmp = Game::GetScannerInfo()->FindMainScript(this, true);
00117 break;
00118 case CONTENT_TYPE_GAME_LIBRARY:
00119 tmp = Game::GetScannerLibrary()->FindMainScript(this, true);
00120 break;
00121 case CONTENT_TYPE_NEWGRF: {
00122 const GRFConfig *gc = FindGRFConfig(BSWAP32(this->unique_id), FGCM_EXACT, this->md5sum);
00123 tmp = gc != NULL ? gc->filename : NULL;
00124 break;
00125 }
00126 case CONTENT_TYPE_BASE_GRAPHICS:
00127 tmp = TryGetBaseSetFile(this, true, BaseGraphics::GetAvailableSets());
00128 break;
00129 case CONTENT_TYPE_BASE_SOUNDS:
00130 tmp = TryGetBaseSetFile(this, true, BaseSounds::GetAvailableSets());
00131 break;
00132 case CONTENT_TYPE_BASE_MUSIC:
00133 tmp = TryGetBaseSetFile(this, true, BaseMusic::GetAvailableSets());
00134 break;
00135 case CONTENT_TYPE_SCENARIO:
00136 case CONTENT_TYPE_HEIGHTMAP:
00137 extern const char *FindScenario(const ContentInfo *ci, bool md5sum);
00138 tmp = FindScenario(this, true);
00139 break;
00140 }
00141 if (tmp == NULL) return NULL;
00142 return ::GetTextfile(type, GetContentInfoSubDir(this->type), tmp);
00143 }
00144 #endif
00145
00146 void NetworkContentSocketHandler::Close()
00147 {
00148 CloseConnection();
00149 if (this->sock == INVALID_SOCKET) return;
00150
00151 closesocket(this->sock);
00152 this->sock = INVALID_SOCKET;
00153 }
00154
00159 #define CONTENT_COMMAND(type) case type: return this->NetworkPacketReceive_ ## type ## _command(p); break;
00160
00167 bool NetworkContentSocketHandler::HandlePacket(Packet *p)
00168 {
00169 PacketContentType type = (PacketContentType)p->Recv_uint8();
00170
00171 switch (this->HasClientQuit() ? PACKET_CONTENT_END : type) {
00172 case PACKET_CONTENT_CLIENT_INFO_LIST: return this->Receive_CLIENT_INFO_LIST(p);
00173 case PACKET_CONTENT_CLIENT_INFO_ID: return this->Receive_CLIENT_INFO_ID(p);
00174 case PACKET_CONTENT_CLIENT_INFO_EXTID: return this->Receive_CLIENT_INFO_EXTID(p);
00175 case PACKET_CONTENT_CLIENT_INFO_EXTID_MD5: return this->Receive_CLIENT_INFO_EXTID_MD5(p);
00176 case PACKET_CONTENT_SERVER_INFO: return this->Receive_SERVER_INFO(p);
00177 case PACKET_CONTENT_CLIENT_CONTENT: return this->Receive_CLIENT_CONTENT(p);
00178 case PACKET_CONTENT_SERVER_CONTENT: return this->Receive_SERVER_CONTENT(p);
00179
00180 default:
00181 if (this->HasClientQuit()) {
00182 DEBUG(net, 0, "[tcp/content] received invalid packet type %d from %s", type, this->client_addr.GetAddressAsString());
00183 } else {
00184 DEBUG(net, 0, "[tcp/content] received illegal packet from %s", this->client_addr.GetAddressAsString());
00185 }
00186 return false;
00187 }
00188 }
00189
00193 void NetworkContentSocketHandler::ReceivePackets()
00194 {
00195 Packet *p;
00196 while ((p = this->ReceivePacket()) != NULL) {
00197 bool cont = this->HandlePacket(p);
00198 delete p;
00199 if (!cont) return;
00200 }
00201 }
00202
00203
00209 bool NetworkContentSocketHandler::ReceiveInvalidPacket(PacketContentType type)
00210 {
00211 DEBUG(net, 0, "[tcp/content] received illegal packet type %d from %s", type, this->client_addr.GetAddressAsString());
00212 return false;
00213 }
00214
00215 bool NetworkContentSocketHandler::Receive_CLIENT_INFO_LIST(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_LIST); }
00216 bool NetworkContentSocketHandler::Receive_CLIENT_INFO_ID(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_ID); }
00217 bool NetworkContentSocketHandler::Receive_CLIENT_INFO_EXTID(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_EXTID); }
00218 bool NetworkContentSocketHandler::Receive_CLIENT_INFO_EXTID_MD5(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_INFO_EXTID_MD5); }
00219 bool NetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_SERVER_INFO); }
00220 bool NetworkContentSocketHandler::Receive_CLIENT_CONTENT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_CLIENT_CONTENT); }
00221 bool NetworkContentSocketHandler::Receive_SERVER_CONTENT(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CONTENT_SERVER_CONTENT); }
00222
00223 #ifndef OPENTTD_MSU
00224
00229 Subdirectory GetContentInfoSubDir(ContentType type)
00230 {
00231 switch (type) {
00232 default: return NO_DIRECTORY;
00233 case CONTENT_TYPE_AI: return AI_DIR;
00234 case CONTENT_TYPE_AI_LIBRARY: return AI_LIBRARY_DIR;
00235 case CONTENT_TYPE_GAME: return GAME_DIR;
00236 case CONTENT_TYPE_GAME_LIBRARY: return GAME_LIBRARY_DIR;
00237 case CONTENT_TYPE_NEWGRF: return NEWGRF_DIR;
00238
00239 case CONTENT_TYPE_BASE_GRAPHICS:
00240 case CONTENT_TYPE_BASE_SOUNDS:
00241 case CONTENT_TYPE_BASE_MUSIC:
00242 return BASESET_DIR;
00243
00244 case CONTENT_TYPE_SCENARIO: return SCENARIO_DIR;
00245 case CONTENT_TYPE_HEIGHTMAP: return HEIGHTMAP_DIR;
00246 }
00247 }
00248 #endif
00249
00250 #endif