12 #if defined(ENABLE_NETWORK) 14 #include "../stdafx.h" 16 #include "../ai/ai.hpp" 17 #include "../game/game.hpp" 18 #include "../window_func.h" 20 #include "../base_media_base.h" 21 #include "../settings_type.h" 24 #include "table/strings.h" 26 #if defined(WITH_ZLIB) 30 #include "../safeguards.h" 65 for (uint j = 0; j <
sizeof(ci->
md5sum); j++) {
107 proc = AI::HasAILibrary;
break;
115 proc = Game::HasGameLibrary;
break;
128 if (proc(ci,
true)) {
132 if (proc(ci,
false)) ci->
upgrade =
true;
225 uint p_count =
min(count, (
SEND_MTU -
sizeof(
PacketSize) -
sizeof(byte) -
sizeof(uint16)) /
sizeof(uint32));
230 for (uint i = 0; i < p_count; i++) {
236 content_ids += p_count;
247 if (cv == NULL)
return;
251 assert(cv->
Length() < 255);
253 (
sizeof(uint8) +
sizeof(uint32) + (send_md5sum ? 16 : 0)));
256 p->Send_uint8(cv->
Length());
260 p->Send_uint8((byte)ci->
type);
262 if (!send_md5sum)
continue;
264 for (uint j = 0; j <
sizeof(ci->
md5sum); j++) {
265 p->Send_uint8(ci->
md5sum[j]);
312 if (files == 0)
return;
327 uint count = content.
Length();
333 uint bytes = (10 + 1) * count + 1;
334 char *content_request = MallocT<char>(bytes);
335 const char *
lastof = content_request + bytes - 1;
337 char *p = content_request;
339 p +=
seprintf(p, lastof,
"%d\n", *
id);
355 uint count = content.
Length();
364 uint p_count =
min(count, (
SEND_MTU -
sizeof(
PacketSize) -
sizeof(byte) -
sizeof(uint16)) /
sizeof(uint32));
369 for (uint i = 0; i < p_count; i++) {
375 content_ids += p_count;
391 static char buf[MAX_PATH];
405 #if defined(WITH_ZLIB) 408 if (ftmp == NULL)
return false;
410 gzFile fin = gzdopen(fileno(ftmp),
"rb");
413 if (fin == NULL || fout == NULL) {
418 int read = gzread(fin, buff,
sizeof(buff));
433 gzerror(fin, &errnum);
434 if (errnum != 0 && errnum != Z_STREAM_END) ret =
false;
437 if (read < 0 || (
size_t)read != fwrite(buff, 1, read, fout)) {
450 }
else if (ftmp != NULL) {
455 if (fout != NULL) fclose(fout);
480 size_t toRead = (size_t)(p->
size - p->
pos);
481 if (fwrite(p->
buffer + p->
pos, 1, toRead, this->curFile) != toRead) {
483 ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD, STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE,
WL_ERROR);
514 if (filename == NULL || (this->
curFile = fopen(filename,
"wb")) == NULL) {
517 ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD, STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE,
WL_ERROR);
568 long size = ftell(this->
curFile);
578 assert(data == NULL || length != 0);
599 if (fwrite(data, 1, length, this->
curFile) != length) {
628 #define check_not_null(p) { if ((p) == NULL) { this->OnFailure(); return; } } 630 #define check_and_terminate(p) { check_not_null(p); *(p) = '\0'; } 634 char *p = strchr(str,
'\n');
635 check_and_terminate(p);
641 p = strchr(str,
',');
642 check_and_terminate(p);
647 p = strchr(str,
',');
648 check_and_terminate(p);
653 p = strchr(str,
',');
654 check_and_terminate(p);
660 if (strncmp(str,
"ottd", 4) == 0) {
669 p = strrchr(str,
'/');
679 for (uint i = 0; i < 2; i++) {
680 p = strrchr(tmp,
'.');
681 check_and_terminate(p);
698 #undef check_and_terminate 735 _network_content_client.
OnConnect(
false);
740 assert(_network_content_client.
sock == INVALID_SOCKET);
742 _network_content_client.
sock = s;
743 _network_content_client.
Reopen();
765 if (this->
sock == INVALID_SOCKET)
return;
817 if (ci->
id == cid)
return ci;
909 if (ci == child)
continue;
933 for (uint i = 0; i < tree.
Length(); i++) {
994 bool force_selection =
false;
996 if ((*iter)->IsSelected()) sel_count++;
999 if (sel_count == 0) {
1005 if (force_selection)
continue;
1015 force_selection =
true;
1020 if (force_selection)
continue;
1052 if (iter != this->
callbacks.
End() && *iter == cb) iter++;
1061 if (iter != this->
callbacks.
End() && *iter == cb) iter++;
1070 if (iter != this->
callbacks.
End() && *iter == cb) iter++;
1079 if (iter != this->
callbacks.
End() && *iter == cb) iter++;
1093 if (iter != this->
callbacks.
End() && *iter == cb) iter++;
Helper to mark the end of the types.
ContentVector infos
All content info we received.
void CheckDependencyState(ContentInfo *ci)
Check the dependencies (recursively) of this content info.
const ContentInfo *const * ConstContentIterator
Iterator for the constant content vector.
The content consists of base graphics.
void OnReceiveContentInfo(const ContentInfo *ci)
We received a content info.
bool IsSelected() const
Is the state either selected or autoselected?
Connect with a HTTP server and do ONE query.
void DownloadSelectedContent(uint &files, uint &bytes, bool fallback=false)
Actually begin downloading the content we selected.
char filename[48]
Filename (for the .tar.gz; only valid on download)
void OnConnect(bool success)
Callback for when the connection has finished.
SOCKET sock
The socket currently connected to.
uint32 unique_id
Unique ID; either GRF ID or shortname.
uint32 _realtime_tick
The real time in the game.
Internal entity of a packet.
Queries the content server for information about a list of external IDs.
static char * strecat(char *dst, const char *src, const char *last)
Appends characters from one string to another.
Socket handler for the content server connection.
Subdirectory
The different kinds of subdirectories OpenTTD uses.
void Close()
Disconnect from the content server.
uint32 Recv_uint32()
Read a 32 bits integer from the packet.
SmallVector< char, 1024 > http_response
The HTTP response to the requests we've been doing.
PacketSize pos
The current read/write position in the packet.
virtual void OnFailure()
Callback for when the connection attempt failed.
"Helper" class for creating TCP connections in a non-blocking manner
static bool GunzipFile(const ContentInfo *ci)
Gunzip a given file and remove the .gz if successful.
Base socket handler for all Content TCP sockets.
void Reset()
Remove all items from the list and free allocated memory.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Callbacks for notifying others about incoming data.
uint32 filesize
Size of the file.
void Connect()
Connect with the content server.
The content consists of a scenario.
void DownloadContentInfo(ContentID cid)
Download information of a given Content ID if not already tried.
uint8 dependency_count
Number of dependencies.
void Send_uint8(uint8 data)
Package a 8 bits integer in the packet.
char(* tags)[32]
Malloced array of tags (strings)
static bool HasGame(const struct ContentInfo *ci, bool md5sum)
Wrapper function for GameScanner::HasGame.
bool(* HasProc)(const ContentInfo *ci, bool md5sum)
Check whether a function piece of content is locally known.
void Clear()
Remove all items from the list.
void SendReceive()
Check whether we received/can send some data from/to the content server and when that's the case hand...
void ReverseLookupTreeDependency(ConstContentVector &tree, const ContentInfo *child) const
Reverse lookup the dependencies of all parents over a given child.
Wrapper for (un)resolved network addresses; there's no reason to transform a numeric IP to a string a...
const T * Begin() const
Get the pointer to the first item (const)
ContentID * dependencies
Malloced array of dependencies (unique server side ids)
virtual void OnConnect(SOCKET s)
Callback when the connection succeeded.
Helper for scanning for files with tar as extension.
The content has been selected as dependency.
void Send_uint32(uint32 data)
Package a 32 bits integer in the packet.
#define lastof(x)
Get the last element of an fixed size array.
SmallVector< ContentCallback *, 2 > callbacks
Callbacks to notify "the world".
const GRFConfig * FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum, uint32 desired_version)
Find a NewGRF in the scanned list.
Subdirectory for all base data (base sets, intro game)
void OnDownloadComplete(ContentID cid)
We have finished downloading a file.
ContentID
Unique identifier for the content.
The content has not been selected.
Queries the content server for information about a list of internal IDs.
void Reopen()
Reopen the socket so we can send/receive stuff again.
const T * End() const
Get the pointer behind the last valid item (const)
SendPacketsState SendPackets(bool closing_down=false)
Sends all the buffered packets out for this client.
void Unselect(ContentID cid)
Unselect a specific content id.
T * Append(uint to_add=1)
Append an item and return it.
The content does not exist in the content system.
bool ReceivePackets()
Receive a packet at TCP level.
void UnselectAll()
Unselect everything that we've not downloaded so far.
bool isConnecting
Whether we're connecting.
virtual bool Receive_SERVER_CONTENT(Packet *p)
Server sending list of content info: uint32 unique id uint32 file size (0 == does not exist) string f...
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=NULL, uint textref_stack_size=0, const uint32 *textref_stack=NULL)
Display an error message in a window.
char name[32]
Name of the content.
virtual void OnDisconnect()
Callback for when the connection got disconnected.
The content consists of a game script.
NetworkSettings network
settings related to the network
~ClientNetworkContentSocketHandler()
Clear up the mess ;)
uint Length() const
Get the number of items in the list.
byte * buffer
The buffer of this packet, of basically variable length up to SEND_MTU.
uint8 tag_count
Number of tags.
char version[16]
Version of the content.
bool Contains(const T &item) const
Tests whether a item is present in the vector.
void SelectUpgrade()
Select everything that's an update for something we've got.
bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename=NULL)
Add a file with the given filename.
void Send_uint16(uint16 data)
Package a 16 bits integer in the packet.
uint32 lastActivity
The last time there was network activity.
static const char *const NETWORK_CONTENT_SERVER_HOST
DNS hostname of the content server.
virtual void OnDownloadProgress(const ContentInfo *ci, int bytes)
We have progress in the download of a file.
static char * GetFullFilename(const ContentInfo *ci, bool compressed)
Determine the full filename of a piece of content information.
ClientSettings _settings_client
The current settings for this game.
A path without any base directory.
The content is already at the client side.
ContentIDList requested
ContentIDs we already requested (so we don't do it again)
ContentID id
Unique (server side) ID for the content.
Connect to the content server.
void Clear()
Clear all downloaded content information.
void RequestContentList(ContentType type)
Request the content list for the given type.
static const char *const NETWORK_CONTENT_MIRROR_HOST
DNS hostname of the HTTP-content mirror server.
State state
Whether the content info is selected (for download)
byte * buf
Buffer we're going to write to/read from.
Search within the autodownload directory.
Part of the network protocol handling content distribution.
PacketSize size
The size of the whole packet for received packets.
void OnReceiveData(const char *data, size_t length)
We're receiving data.
void TransferFrom(ContentInfo *other)
Copy data from other ContentInfo and take ownership of allocated stuff.
void OnDownloadProgress(const ContentInfo *ci, int bytes)
We have progress in the download of a file.
#define lengthof(x)
Return the length of an fixed size array.
static T min(const T a, const T b)
Returns the minimum of two values.
static const int IDLE_TIMEOUT
The idle timeout; when to close the connection because it's idle.
Queries the content server for a list of info of a given content type.
byte md5sum[16]
The MD5 checksum.
The content consists of a GS library.
bool BeforeDownload()
Handle the opening of the file before downloading.
static bool HasAI(const struct ContentInfo *ci, bool md5sum)
Wrapper function for AIScanner::HasAI.
ContentInfo * GetContent(ContentID cid)
Get the content info based on a ContentID.
The content consists of a NewGRF.
ContentType
The values in the enum are important; they are used as database 'keys'.
Network status window; Window numbers:
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Queries the content server for information about a list of external IDs and MD5.
void Select(ContentID cid)
Select a specific content id.
The content consists of an AI library.
uint8 Recv_uint8()
Read a 8 bits integer from the packet.
void SelectAll()
Select everything we can select.
void ReverseLookupDependency(ConstContentVector &parents, const ContentInfo *child) const
Reverse lookup the dependencies of (direct) parents over a given child.
Request a content file given an internal ID.
static const char *const NETWORK_CONTENT_MIRROR_URL
URL of the HTTP mirror system.
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Replace the unknown/bad bits with question marks.
The content consists of a heightmap.
The content consists of an AI.
ContentType type
Type of content.
bool upgrade
This item is an upgrade.
void DownloadSelectedContentFallback(const ContentIDList &content)
Initiate downloading the content over the fallback protocol.
void AfterDownload()
Handle the closing and extracting of a file after downloading it has been done.
static const uint16 NETWORK_CONTENT_MIRROR_PORT
The default port of the content mirror (TCP)
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
virtual bool Receive_SERVER_INFO(Packet *p)
Server sending list of content info: byte type (invalid ID == does not exist) uint32 id uint32 file_s...
The content consists of base music.
bool Include(const T &item)
Tests whether a item is present in the vector, and appends it to the end if not.
bool no_http_content_downloads
do not do content downloads over HTTP
virtual void OnReceiveContentInfo(const ContentInfo *ci)
We received a content info.
bool HasScenario(const ContentInfo *ci, bool md5sum)
Check whether we've got a given scenario based on its unique ID.
ClientNetworkContentSocketHandler()
Create a socket handler to handle the connection.
static const uint16 SEND_MTU
Number of bytes we can pack in a single packet.
NetworkContentConnecter(const NetworkAddress &address)
Initiate the connecting.
virtual void Close()
Really close the socket.
ContentInfo * curInfo
Information about the currently downloaded file.
virtual void OnConnect(bool success)
Callback for when the connection has finished.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
bool ExtractTar(const char *tar_filename, Subdirectory subdir)
Extract the tar with the given filename in the directory where the tar resides.
static int Connect(char *uri, HTTPCallback *callback, const char *data=NULL, int depth=0)
Connect to the given URI.
The content has been manually selected.
virtual void SendPacket(Packet *packet)
This function puts the packet in the send-queue and it is send as soon as possible.
void OnFailure()
An error has occurred and the connection has been closed.
static const uint16 NETWORK_CONTENT_SERVER_PORT
The default port of the content server (TCP)
int http_response_index
Where we are, in the response, with handling it.
virtual void OnDownloadComplete(ContentID cid)
We have finished downloading a file.
bool CanSendReceive()
Check whether this socket can send or receive something.
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
Only find Grfs matching md5sum.
Subdirectory GetContentInfoSubDir(ContentType type)
Helper to get the subdirectory a ContentInfo is located in.
char url[96]
URL related to the content.
static bool HasGRFConfig(const ContentInfo *ci, bool md5sum)
Wrapper function for the HasProc.
Errors (eg. saving/loading failed)
void DownloadSelectedContentHTTP(const ContentIDList &content)
Initiate downloading the content over HTTP.
char description[512]
Description of the content.
uint16 PacketSize
Size of the whole packet.
FILE * curFile
Currently downloaded file.
Container for all important information about a piece of content.
bool IsValid() const
Is the information from this content info valid?
Network content download status.
ClientNetworkContentSocketHandler _network_content_client
The client we use to connect to the server.
void Recv_string(char *buffer, size_t size, StringValidationSettings settings=SVS_REPLACE_WITH_QUESTION_MARK)
Reads a string till it finds a '\0' in the stream.
void ToggleSelectedState(const ContentInfo *ci)
Toggle the state of a content info and check its dependencies.
The content consists of base sounds.
void OnDisconnect()
Callback for when the connection got disconnected.