Changeset - r25616:f6fb8fecc5a4
[Not reviewed]
master
0 5 0
rubidium42 - 3 years ago 2021-05-30 10:47:50
rubidium@openttd.org
Codechange: [ContentInfo] Use StringList for tags instead of custom allocations
5 files changed with 12 insertions and 15 deletions:
0 comments (0 inline, 0 general)
src/network/core/config.h
Show inline comments
 
@@ -56,24 +56,25 @@ static const byte NETWORK_MASTER_SERVER_
 
static const uint NETWORK_NAME_LENGTH             =   80;         ///< The maximum length of the server name and map name, in bytes including '\0'
 
static const uint NETWORK_COMPANY_NAME_LENGTH     =  128;         ///< The maximum length of the company name, in bytes including '\0'
 
static const uint NETWORK_HOSTNAME_LENGTH         =   80;         ///< The maximum length of the host name, in bytes including '\0'
 
static const uint NETWORK_HOSTNAME_PORT_LENGTH    =   80 + 6;     ///< The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port number (with a max of 65536)
 
static const uint NETWORK_SERVER_ID_LENGTH        =   33;         ///< The maximum length of the network id of the servers, in bytes including '\0'
 
static const uint NETWORK_REVISION_LENGTH         =   33;         ///< The maximum length of the revision, in bytes including '\0'
 
static const uint NETWORK_PASSWORD_LENGTH         =   33;         ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH)
 
static const uint NETWORK_CLIENTS_LENGTH          =  200;         ///< The maximum length for the list of clients that controls a company, in bytes including '\0'
 
static const uint NETWORK_CLIENT_NAME_LENGTH      =   25;         ///< The maximum length of a client's name, in bytes including '\0'
 
static const uint NETWORK_RCONCOMMAND_LENGTH      =  500;         ///< The maximum length of a rconsole command, in bytes including '\0'
 
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH  = COMPAT_MTU-3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes)
 
static const uint NETWORK_CHAT_LENGTH             =  900;         ///< The maximum length of a chat message, in bytes including '\0'
 
static const uint NETWORK_CONTENT_TAG_LENGTH      =   32;         ///< The maximum length of a content's tag, in bytes including '\0'.
 

	
 
static const uint NETWORK_GRF_NAME_LENGTH         =   80;         ///< Maximum length of the name of a GRF
 

	
 
/**
 
 * Maximum number of GRFs that can be sent.
 
 * This limit is reached when PACKET_UDP_SERVER_RESPONSE reaches the maximum size of UDP_MTU bytes.
 
 */
 
static const uint NETWORK_MAX_GRF_COUNT           =   62;
 

	
 
/**
 
 * The number of landscapes in OpenTTD.
 
 * This number must be equal to NUM_LANDSCAPE, but as this number is used
src/network/core/tcp_content.cpp
Show inline comments
 
@@ -16,47 +16,45 @@
 
#include "../../ai/ai.hpp"
 
#include "../../game/game.hpp"
 
#include "../../fios.h"
 
#include "tcp_content.h"
 

	
 
#include "../../safeguards.h"
 

	
 
/** Clear everything in the struct */
 
ContentInfo::ContentInfo()
 
	: /* Temporary... will be removed later in the PR. */
 
	type((ContentType)0), id((ContentID)0), filesize(0), filename(""), name(""), version(""),
 
	url(""), description(""), unique_id(0), md5sum(""), dependency_count(0), dependencies(nullptr),
 
	tag_count(0), tags(nullptr), state((State)0), upgrade(false)
 
	state((State)0), upgrade(false)
 
{
 
}
 

	
 
/** Free everything allocated */
 
ContentInfo::~ContentInfo()
 
{
 
	free(this->dependencies);
 
	free(this->tags);
 
}
 

	
 
/**
 
 * Copy data from other #ContentInfo and take ownership of allocated stuff.
 
 * @param other Source to copy from. #dependencies and #tags will be NULLed.
 
 */
 
void ContentInfo::TransferFrom(ContentInfo *other)
 
{
 
	if (other != this) {
 
		free(this->dependencies);
 
		free(this->tags);
 
		*this = *other;
 
		other->dependencies = nullptr;
 
		other->tags = nullptr;
 
		other->tags.clear();
 
	}
 
}
 

	
 
/**
 
 * Is the state either selected or autoselected?
 
 * @return true iff that's the case
 
 */
 
bool ContentInfo::IsSelected() const
 
{
 
	switch (this->state) {
 
		case ContentInfo::SELECTED:
 
		case ContentInfo::AUTOSELECTED:
src/network/core/tcp_content_type.h
Show inline comments
 
@@ -60,26 +60,25 @@ struct ContentInfo {
 
	ContentType type;        ///< Type of content
 
	ContentID id;            ///< Unique (server side) ID for the content
 
	uint32 filesize;         ///< Size of the file
 
	char filename[48];       ///< Filename (for the .tar.gz; only valid on download)
 
	char name[32];           ///< Name of the content
 
	char version[16];        ///< Version of the content
 
	char url[96];            ///< URL related to the content
 
	char description[512];   ///< Description of the content
 
	uint32 unique_id;        ///< Unique ID; either GRF ID or shortname
 
	byte md5sum[16];         ///< The MD5 checksum
 
	uint8 dependency_count;  ///< Number of dependencies
 
	ContentID *dependencies; ///< Malloced array of dependencies (unique server side ids)
 
	uint8 tag_count;         ///< Number of tags
 
	char (*tags)[32];        ///< Malloced array of tags (strings)
 
	StringList tags;         ///< Tags associated with the content
 
	State state;             ///< Whether the content info is selected (for download)
 
	bool upgrade;            ///< This item is an upgrade
 

	
 
	ContentInfo();
 
	~ContentInfo();
 

	
 
	void TransferFrom(ContentInfo *other);
 

	
 
	bool IsSelected() const;
 
	bool IsValid() const;
 
	const char *GetTextfile(TextfileType type) const;
 
};
src/network/network_content.cpp
Show inline comments
 
@@ -61,27 +61,27 @@ bool ClientNetworkContentSocketHandler::
 
	p->Recv_string(ci->url, lengthof(ci->url));
 
	p->Recv_string(ci->description, lengthof(ci->description), SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE);
 

	
 
	ci->unique_id = p->Recv_uint32();
 
	for (uint j = 0; j < sizeof(ci->md5sum); j++) {
 
		ci->md5sum[j] = p->Recv_uint8();
 
	}
 

	
 
	ci->dependency_count = p->Recv_uint8();
 
	ci->dependencies = MallocT<ContentID>(ci->dependency_count);
 
	for (uint i = 0; i < ci->dependency_count; i++) ci->dependencies[i] = (ContentID)p->Recv_uint32();
 

	
 
	ci->tag_count = p->Recv_uint8();
 
	ci->tags = MallocT<char[32]>(ci->tag_count);
 
	for (uint i = 0; i < ci->tag_count; i++) p->Recv_string(ci->tags[i], lengthof(*ci->tags));
 
	uint tag_count = p->Recv_uint8();
 
	ci->tags.reserve(tag_count);
 
	for (uint i = 0; i < tag_count; i++) ci->tags.push_back(p->Recv_string(NETWORK_CONTENT_TAG_LENGTH));
 

	
 
	if (!ci->IsValid()) {
 
		delete ci;
 
		this->CloseConnection();
 
		return false;
 
	}
 

	
 
	/* Find the appropriate check function */
 
	HasProc proc = nullptr;
 
	switch (ci->type) {
 
		case CONTENT_TYPE_NEWGRF:
 
			proc = HasGRFConfig;
src/network/network_content_gui.cpp
Show inline comments
 
@@ -434,27 +434,26 @@ class NetworkContentListWindow : public 
 
	void SortContentList()
 
	{
 
		if (!this->content.Sort()) return;
 

	
 
		int idx = find_index(this->content, this->selected);
 
		if (idx >= 0) this->list_pos = idx;
 
	}
 

	
 
	/** Filter content by tags/name */
 
	static bool CDECL TagNameFilter(const ContentInfo * const *a, ContentListFilterData &filter)
 
	{
 
		filter.string_filter.ResetState();
 
		for (int i = 0; i < (*a)->tag_count; i++) {
 
			filter.string_filter.AddLine((*a)->tags[i]);
 
		}
 
		for (auto &tag : (*a)->tags) filter.string_filter.AddLine(tag.c_str());
 

	
 
		filter.string_filter.AddLine((*a)->name);
 
		return filter.string_filter.GetState();
 
	}
 

	
 
	/** Filter content by type, but still show content selected for download. */
 
	static bool CDECL TypeOrSelectedFilter(const ContentInfo * const *a, ContentListFilterData &filter)
 
	{
 
		if (filter.types.none()) return true;
 
		if (filter.types[(*a)->type]) return true;
 
		return ((*a)->state == ContentInfo::SELECTED || (*a)->state == ContentInfo::AUTOSELECTED);
 
	}
 

	
 
@@ -738,30 +737,30 @@ public:
 
				for (; iter != _network_content_client.End(); iter++) {
 
					const ContentInfo *ci = *iter;
 
					if (ci->id != cid) continue;
 

	
 
					p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", (*iter)->name);
 
					break;
 
				}
 
			}
 
			SetDParamStr(0, buf);
 
			y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DEPENDENCIES);
 
		}
 

	
 
		if (this->selected->tag_count != 0) {
 
		if (!this->selected->tags.empty()) {
 
			/* List all tags */
 
			char buf[DRAW_STRING_BUFFER] = "";
 
			char *p = buf;
 
			for (uint i = 0; i < this->selected->tag_count; i++) {
 
				p += seprintf(p, lastof(buf), i == 0 ? "%s" : ", %s", this->selected->tags[i]);
 
			for (auto &tag : this->selected->tags) {
 
				p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", tag.c_str());
 
			}
 
			SetDParamStr(0, buf);
 
			y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_TAGS);
 
		}
 

	
 
		if (this->selected->IsSelected()) {
 
			/* When selected show all manually selected content that depends on this */
 
			ConstContentVector tree;
 
			_network_content_client.ReverseLookupTreeDependency(tree, this->selected);
 

	
 
			char buf[DRAW_STRING_BUFFER] = "";
 
			char *p = buf;
0 comments (0 inline, 0 general)