OpenTTD Source 20241224-master-gf74b0cf984
tcp_content.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
12#include "../../stdafx.h"
13#include "../../textfile_gui.h"
14#include "../../newgrf_config.h"
15#include "../../base_media_base.h"
16#include "../../ai/ai.hpp"
17#include "../../game/game.hpp"
18#include "../../fios.h"
19#include "tcp_content.h"
20
21#include "../../safeguards.h"
22
28{
29 switch (this->state) {
33 return true;
34
35 default:
36 return false;
37 }
38}
39
45{
46 return this->state < ContentInfo::INVALID && this->type >= CONTENT_TYPE_BEGIN && this->type < CONTENT_TYPE_END;
47}
48
54std::optional<std::string> ContentInfo::GetTextfile(TextfileType type) const
55{
56 if (this->state == INVALID) return std::nullopt;
57 const char *tmp;
58 switch (this->type) {
59 default: NOT_REACHED();
60 case CONTENT_TYPE_AI:
61 tmp = AI::GetScannerInfo()->FindMainScript(this, true);
62 break;
64 tmp = AI::GetScannerLibrary()->FindMainScript(this, true);
65 break;
67 tmp = Game::GetScannerInfo()->FindMainScript(this, true);
68 break;
70 tmp = Game::GetScannerLibrary()->FindMainScript(this, true);
71 break;
73 const GRFConfig *gc = FindGRFConfig(BSWAP32(this->unique_id), FGCM_EXACT, &this->md5sum);
74 tmp = gc != nullptr ? gc->filename.c_str() : nullptr;
75 break;
76 }
79 break;
82 break;
85 break;
88 tmp = FindScenario(this, true);
89 break;
90 }
91 if (tmp == nullptr) return std::nullopt;
92 return ::GetTextfile(type, GetContentInfoSubDir(this->type), tmp);
93}
94
102{
104
105 switch (this->HasClientQuit() ? PACKET_CONTENT_END : type) {
113
114 default:
115 if (this->HasClientQuit()) {
116 Debug(net, 0, "[tcp/content] Received invalid packet type {}", type);
117 } else {
118 Debug(net, 0, "[tcp/content] Received illegal packet");
119 }
120 return false;
121 }
122}
123
129{
130 /*
131 * We read only a few of the packets. This as receiving packets can be expensive
132 * due to the re-resolving of the parent/child relations and checking the toggle
133 * state of all bits. We cannot do this all in one go, as we want to show the
134 * user what we already received. Otherwise, it can take very long before any
135 * progress is shown to the end user that something has been received.
136 * It is also the case that we request extra content from the content server in
137 * case there is an unknown (in the content list) piece of content. These will
138 * come in after the main lists have been requested. As a result, we won't be
139 * getting everything reliably in one batch. Thus, we need to make subsequent
140 * updates in that case as well.
141 *
142 * As a result, we simple handle an arbitrary number of packets in one cycle,
143 * and let the rest be handled in subsequent cycles. These are ran, almost,
144 * immediately after this cycle so in speed it does not matter much, except
145 * that the user inferface will appear better responding.
146 *
147 * What arbitrary number to choose is the ultimate question though.
148 */
149 std::unique_ptr<Packet> p;
150 static const int MAX_PACKETS_TO_RECEIVE = 42;
151 int i = MAX_PACKETS_TO_RECEIVE;
152 while (--i != 0 && (p = this->ReceivePacket()) != nullptr) {
153 bool cont = this->HandlePacket(*p);
154 if (!cont) return true;
155 }
156
157 return i != MAX_PACKETS_TO_RECEIVE - 1;
158}
159
160
167{
168 Debug(net, 0, "[tcp/content] Received illegal packet type {}", type);
169 return false;
170}
171
179
186{
187 switch (type) {
188 default: return NO_DIRECTORY;
189 case CONTENT_TYPE_AI: return AI_DIR;
191 case CONTENT_TYPE_GAME: return GAME_DIR;
193 case CONTENT_TYPE_NEWGRF: return NEWGRF_DIR;
194
198 return BASESET_DIR;
199
202 }
203}
const char * TryGetBaseSetFile(const ContentInfo *ci, bool md5sum, const Tbase_set *s)
Check whether there's a base set matching some information.
static uint32_t BSWAP32(uint32_t x)
Perform a 32 bits endianness bitswap on x.
static AIScannerLibrary * GetScannerLibrary()
Gets the ScriptScanner instance that is used to find AI Libraries.
Definition ai_core.cpp:360
static AIScannerInfo * GetScannerInfo()
Gets the ScriptScanner instance that is used to find AIs.
Definition ai_core.cpp:355
static GraphicsSet * GetAvailableSets()
Return the available sets.
static GameScannerLibrary * GetScannerLibrary()
Gets the ScriptScanner instance that is used to find Game Libraries.
static GameScannerInfo * GetScannerInfo()
Gets the ScriptScanner instance that is used to find Game scripts.
virtual bool Receive_CLIENT_CONTENT(Packet &p)
Client requesting the actual content: uint16_t count of unique ids uint32_t unique id (count times)
virtual bool Receive_CLIENT_INFO_EXTID(Packet &p)
Client requesting a list of content info based on an external 'unique' id; GRF ID for NewGRFS,...
virtual bool Receive_CLIENT_INFO_EXTID_MD5(Packet &p)
Client requesting a list of content info based on an external 'unique' id; GRF ID + MD5 checksum for ...
virtual bool Receive_SERVER_INFO(Packet &p)
Server sending list of content info: uint8_t type (invalid ID == does not exist) uint32_t id uint32_t...
virtual bool Receive_CLIENT_INFO_ID(Packet &p)
Client requesting a list of content info: uint16_t count of ids uint32_t id (count times)
virtual bool Receive_SERVER_CONTENT(Packet &p)
Server sending list of content info: uint32_t unique id uint32_t file size (0 == does not exist) stri...
bool ReceivePackets()
Receive a packet at TCP level.
virtual bool Receive_CLIENT_INFO_LIST(Packet &p)
Client requesting a list of content info: uint8_t type uint32_t openttd version (or 0xFFFFFFFF if usi...
bool ReceiveInvalidPacket(PacketContentType type)
Helper for logging receiving invalid packets.
bool HandlePacket(Packet &p)
Handle the given packet, i.e.
bool HasClientQuit() const
Whether the current client connected to the socket has quit.
Definition core.h:74
virtual std::unique_ptr< Packet > ReceivePacket()
Receives a packet for the given client.
Definition tcp.cpp:129
const char * FindMainScript(const ContentInfo *ci, bool md5sum)
Find a script of a ContentInfo.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition debug.h:37
Subdirectory
The different kinds of subdirectories OpenTTD uses.
@ NO_DIRECTORY
A path without any base directory.
@ AI_LIBRARY_DIR
Subdirectory for all AI libraries.
@ GAME_LIBRARY_DIR
Subdirectory for all GS libraries.
@ AI_DIR
Subdirectory for all AI files.
@ SCENARIO_DIR
Base directory for all scenarios.
@ HEIGHTMAP_DIR
Subdirectory of scenario for heightmaps.
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
@ GAME_DIR
Subdirectory for all game scripts.
const char * FindScenario(const ContentInfo *ci, bool md5sum)
Find a given scenario based on its unique ID.
Definition fios.cpp:690
const GRFConfig * FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
Find a NewGRF in the scanned list.
@ FGCM_EXACT
Only find Grfs matching md5sum.
uint32_t unique_id
Unique ID; either GRF ID or shortname.
bool IsValid() const
Is the information from this content info valid?
MD5Hash md5sum
The MD5 checksum.
State state
Whether the content info is selected (for download)
std::optional< std::string > GetTextfile(TextfileType type) const
Search a textfile file next to this file in the content list.
@ ALREADY_HERE
The content is already at the client side.
@ AUTOSELECTED
The content has been selected as dependency.
@ INVALID
The content's invalid.
@ SELECTED
The content has been manually selected.
bool IsSelected() const
Is the state either selected or autoselected?
ContentType type
Type of content.
Information about GRF, used in the game and (part of it) in savegames.
std::string filename
Filename - either with or without full path.
Internal entity of a packet.
Definition packet.h:42
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition packet.cpp:318
Subdirectory GetContentInfoSubDir(ContentType type)
Helper to get the subdirectory a ContentInfo is located in.
Basic functions to receive and send TCP packets to/from the content server.
ContentType
The values in the enum are important; they are used as database 'keys'.
@ CONTENT_TYPE_AI_LIBRARY
The content consists of an AI library.
@ CONTENT_TYPE_BASE_SOUNDS
The content consists of base sounds.
@ CONTENT_TYPE_GAME_LIBRARY
The content consists of a GS library.
@ CONTENT_TYPE_BASE_GRAPHICS
The content consists of base graphics.
@ CONTENT_TYPE_AI
The content consists of an AI.
@ CONTENT_TYPE_SCENARIO
The content consists of a scenario.
@ CONTENT_TYPE_NEWGRF
The content consists of a NewGRF.
@ CONTENT_TYPE_BEGIN
Helper to mark the begin of the types.
@ CONTENT_TYPE_BASE_MUSIC
The content consists of base music.
@ CONTENT_TYPE_GAME
The content consists of a game script.
@ CONTENT_TYPE_END
Helper to mark the end of the types.
@ CONTENT_TYPE_HEIGHTMAP
The content consists of a heightmap.
PacketContentType
Enum with all types of TCP content packets.
@ PACKET_CONTENT_CLIENT_CONTENT
Request a content file given an internal ID.
@ PACKET_CONTENT_END
Must ALWAYS be on the end of this list!! (period)
@ PACKET_CONTENT_CLIENT_INFO_LIST
Queries the content server for a list of info of a given content type.
@ PACKET_CONTENT_CLIENT_INFO_EXTID_MD5
Queries the content server for information about a list of external IDs and MD5.
@ PACKET_CONTENT_SERVER_INFO
Reply of content server with information about content.
@ PACKET_CONTENT_SERVER_CONTENT
Reply with the content of the given ID.
@ PACKET_CONTENT_CLIENT_INFO_ID
Queries the content server for information about a list of internal IDs.
@ PACKET_CONTENT_CLIENT_INFO_EXTID
Queries the content server for information about a list of external IDs.
TextfileType
Additional text files accompanying Tar archives.