OpenTTD Source  20240919-master-gdf0233f4c2
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 
54 std::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;
66  case CONTENT_TYPE_GAME:
67  tmp = Game::GetScannerInfo()->FindMainScript(this, true);
68  break;
70  tmp = Game::GetScannerLibrary()->FindMainScript(this, true);
71  break;
72  case CONTENT_TYPE_NEWGRF: {
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;
93 }
94 
102 {
104 
105  switch (this->HasClientQuit() ? PACKET_CONTENT_END : type) {
110  case PACKET_CONTENT_SERVER_INFO: return this->Receive_SERVER_INFO(p);
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 
200  case CONTENT_TYPE_SCENARIO: return SCENARIO_DIR;
202  }
203 }
ContentInfo::IsSelected
bool IsSelected() const
Is the state either selected or autoselected?
Definition: tcp_content.cpp:27
BaseMedia< GraphicsSet >::GetAvailableSets
static GraphicsSet * GetAvailableSets()
Return the available sets.
Definition: base_media_func.h:404
ContentInfo::GetTextfile
std::optional< std::string > GetTextfile(TextfileType type) const
Search a textfile file next to this file in the content list.
Definition: tcp_content.cpp:54
ContentInfo::type
ContentType type
Type of content.
Definition: tcp_content_type.h:63
AI::GetScannerInfo
static AIScannerInfo * GetScannerInfo()
Gets the ScriptScanner instance that is used to find AIs.
Definition: ai_core.cpp:364
NetworkContentSocketHandler::Receive_CLIENT_CONTENT
virtual bool Receive_CLIENT_CONTENT(Packet &p)
Client requesting the actual content: uint16_t count of unique ids uint32_t unique id (count times)
Definition: tcp_content.cpp:177
PACKET_CONTENT_CLIENT_INFO_EXTID
@ PACKET_CONTENT_CLIENT_INFO_EXTID
Queries the content server for information about a list of external IDs.
Definition: tcp_content_type.h:38
CONTENT_TYPE_GAME_LIBRARY
@ CONTENT_TYPE_GAME_LIBRARY
The content consists of a GS library.
Definition: tcp_content_type.h:29
BASESET_DIR
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition: fileio_type.h:123
GAME_LIBRARY_DIR
@ GAME_LIBRARY_DIR
Subdirectory for all GS libraries.
Definition: fileio_type.h:129
TryGetBaseSetFile
const char * TryGetBaseSetFile(const ContentInfo *ci, bool md5sum, const Tbase_set *s)
Check whether there's a base set matching some information.
Definition: base_media_func.h:319
NetworkContentSocketHandler::Receive_CLIENT_INFO_ID
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)
Definition: tcp_content.cpp:173
CONTENT_TYPE_NEWGRF
@ CONTENT_TYPE_NEWGRF
The content consists of a NewGRF.
Definition: tcp_content_type.h:21
GRFConfig::filename
std::string filename
Filename - either with or without full path.
Definition: newgrf_config.h:156
NetworkContentSocketHandler::Receive_CLIENT_INFO_EXTID
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,...
Definition: tcp_content.cpp:174
HEIGHTMAP_DIR
@ HEIGHTMAP_DIR
Subdirectory of scenario for heightmaps.
Definition: fileio_type.h:120
NetworkContentSocketHandler::ReceivePackets
bool ReceivePackets()
Receive a packet at TCP level.
Definition: tcp_content.cpp:128
CONTENT_TYPE_END
@ CONTENT_TYPE_END
Helper to mark the end of the types.
Definition: tcp_content_type.h:30
ContentInfo::md5sum
MD5Hash md5sum
The MD5 checksum.
Definition: tcp_content_type.h:72
ContentInfo::IsValid
bool IsValid() const
Is the information from this content info valid?
Definition: tcp_content.cpp:44
ContentType
ContentType
The values in the enum are important; they are used as database 'keys'.
Definition: tcp_content_type.h:18
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
GetContentInfoSubDir
Subdirectory GetContentInfoSubDir(ContentType type)
Helper to get the subdirectory a ContentInfo is located in.
Definition: tcp_content.cpp:185
Game::GetScannerLibrary
static GameScannerLibrary * GetScannerLibrary()
Gets the ScriptScanner instance that is used to find Game Libraries.
Definition: game_core.cpp:272
tcp_content.h
CONTENT_TYPE_GAME
@ CONTENT_TYPE_GAME
The content consists of a game script.
Definition: tcp_content_type.h:28
BSWAP32
static uint32_t BSWAP32(uint32_t x)
Perform a 32 bits endianness bitswap on x.
Definition: bitmath_func.hpp:364
PacketContentType
PacketContentType
Enum with all types of TCP content packets.
Definition: tcp_content_type.h:35
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition: newgrf_config.h:147
AI_DIR
@ AI_DIR
Subdirectory for all AI files.
Definition: fileio_type.h:126
GetTextfile
std::optional< std::string > GetTextfile(TextfileType type, Subdirectory dir, const std::string &filename)
Search a textfile file next to the given content.
Definition: textfile_gui.cpp:830
AI::GetScannerLibrary
static AIScannerLibrary * GetScannerLibrary()
Gets the ScriptScanner instance that is used to find AI Libraries.
Definition: ai_core.cpp:369
GAME_DIR
@ GAME_DIR
Subdirectory for all game scripts.
Definition: fileio_type.h:128
PACKET_CONTENT_SERVER_INFO
@ PACKET_CONTENT_SERVER_INFO
Reply of content server with information about content.
Definition: tcp_content_type.h:40
SCENARIO_DIR
@ SCENARIO_DIR
Base directory for all scenarios.
Definition: fileio_type.h:119
ContentInfo::SELECTED
@ SELECTED
The content has been manually selected.
Definition: tcp_content_type.h:56
Packet
Internal entity of a packet.
Definition: packet.h:42
NetworkContentSocketHandler::Receive_CLIENT_INFO_EXTID_MD5
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 ...
Definition: tcp_content.cpp:175
PACKET_CONTENT_CLIENT_CONTENT
@ PACKET_CONTENT_CLIENT_CONTENT
Request a content file given an internal ID.
Definition: tcp_content_type.h:41
NEWGRF_DIR
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
Definition: fileio_type.h:124
NetworkContentSocketHandler::Receive_CLIENT_INFO_LIST
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...
Definition: tcp_content.cpp:172
NetworkContentSocketHandler::ReceiveInvalidPacket
bool ReceiveInvalidPacket(PacketContentType type)
Helper for logging receiving invalid packets.
Definition: tcp_content.cpp:166
PACKET_CONTENT_CLIENT_INFO_LIST
@ PACKET_CONTENT_CLIENT_INFO_LIST
Queries the content server for a list of info of a given content type.
Definition: tcp_content_type.h:36
NetworkContentSocketHandler::HandlePacket
bool HandlePacket(Packet &p)
Handle the given packet, i.e.
Definition: tcp_content.cpp:101
CONTENT_TYPE_AI
@ CONTENT_TYPE_AI
The content consists of an AI.
Definition: tcp_content_type.h:22
PACKET_CONTENT_CLIENT_INFO_ID
@ PACKET_CONTENT_CLIENT_INFO_ID
Queries the content server for information about a list of internal IDs.
Definition: tcp_content_type.h:37
NetworkSocketHandler::HasClientQuit
bool HasClientQuit() const
Whether the current client connected to the socket has quit.
Definition: core.h:74
CONTENT_TYPE_BASE_GRAPHICS
@ CONTENT_TYPE_BASE_GRAPHICS
The content consists of base graphics.
Definition: tcp_content_type.h:20
ContentInfo::ALREADY_HERE
@ ALREADY_HERE
The content is already at the client side.
Definition: tcp_content_type.h:58
NetworkContentSocketHandler::Receive_SERVER_INFO
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...
Definition: tcp_content.cpp:176
ContentInfo::AUTOSELECTED
@ AUTOSELECTED
The content has been selected as dependency.
Definition: tcp_content_type.h:57
CONTENT_TYPE_AI_LIBRARY
@ CONTENT_TYPE_AI_LIBRARY
The content consists of an AI library.
Definition: tcp_content_type.h:23
NO_DIRECTORY
@ NO_DIRECTORY
A path without any base directory.
Definition: fileio_type.h:133
CONTENT_TYPE_BEGIN
@ CONTENT_TYPE_BEGIN
Helper to mark the begin of the types.
Definition: tcp_content_type.h:19
Subdirectory
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition: fileio_type.h:115
NetworkTCPSocketHandler::ReceivePacket
virtual std::unique_ptr< Packet > ReceivePacket()
Receives a packet for the given client.
Definition: tcp.cpp:129
ContentInfo::state
State state
Whether the content info is selected (for download)
Definition: tcp_content_type.h:75
CONTENT_TYPE_BASE_SOUNDS
@ CONTENT_TYPE_BASE_SOUNDS
The content consists of base sounds.
Definition: tcp_content_type.h:26
AI_LIBRARY_DIR
@ AI_LIBRARY_DIR
Subdirectory for all AI libraries.
Definition: fileio_type.h:127
NetworkContentSocketHandler::Receive_SERVER_CONTENT
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...
Definition: tcp_content.cpp:178
Game::GetScannerInfo
static GameScannerInfo * GetScannerInfo()
Gets the ScriptScanner instance that is used to find Game scripts.
Definition: game_core.cpp:268
PACKET_CONTENT_CLIENT_INFO_EXTID_MD5
@ PACKET_CONTENT_CLIENT_INFO_EXTID_MD5
Queries the content server for information about a list of external IDs and MD5.
Definition: tcp_content_type.h:39
CONTENT_TYPE_SCENARIO
@ CONTENT_TYPE_SCENARIO
The content consists of a scenario.
Definition: tcp_content_type.h:24
PACKET_CONTENT_END
@ PACKET_CONTENT_END
Must ALWAYS be on the end of this list!! (period)
Definition: tcp_content_type.h:43
TextfileType
TextfileType
Additional text files accompanying Tar archives.
Definition: textfile_type.h:14
FGCM_EXACT
@ FGCM_EXACT
Only find Grfs matching md5sum.
Definition: newgrf_config.h:192
ScriptScanner::FindMainScript
const char * FindMainScript(const ContentInfo *ci, bool md5sum)
Find a script of a ContentInfo.
Definition: script_scanner.cpp:243
ContentInfo::INVALID
@ INVALID
The content's invalid.
Definition: tcp_content_type.h:60
FindScenario
const char * FindScenario(const ContentInfo *ci, bool md5sum)
Find a given scenario based on its unique ID.
Definition: fios.cpp:690
FindGRFConfig
const GRFConfig * FindGRFConfig(uint32_t grfid, FindGRFConfigMode mode, const MD5Hash *md5sum, uint32_t desired_version)
Find a NewGRF in the scanned list.
Definition: newgrf_config.cpp:686
CONTENT_TYPE_HEIGHTMAP
@ CONTENT_TYPE_HEIGHTMAP
The content consists of a heightmap.
Definition: tcp_content_type.h:25
PACKET_CONTENT_SERVER_CONTENT
@ PACKET_CONTENT_SERVER_CONTENT
Reply with the content of the given ID.
Definition: tcp_content_type.h:42
ContentInfo::unique_id
uint32_t unique_id
Unique ID; either GRF ID or shortname.
Definition: tcp_content_type.h:71
Packet::Recv_uint8
uint8_t Recv_uint8()
Read a 8 bits integer from the packet.
Definition: packet.cpp:318
CONTENT_TYPE_BASE_MUSIC
@ CONTENT_TYPE_BASE_MUSIC
The content consists of base music.
Definition: tcp_content_type.h:27