Changeset - r17403:bbaee031fd60
[Not reviewed]
master
0 5 0
yexo - 13 years ago 2011-03-03 18:47:46
yexo@openttd.org
(svn r22162) -Fix [FS#4533]: No update of NewGRF window when unknown GRF name becomes available
5 files changed with 81 insertions and 37 deletions:
0 comments (0 inline, 0 general)
src/network/network_gamelist.cpp
Show inline comments
 
@@ -179,23 +179,28 @@ void NetworkAfterNewGRFScan()
 

	
 
			const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, c->ident.md5sum);
 
			if (f == NULL) {
 
				/* Don't know the GRF, so mark game incompatible and the (possibly)
 
				 * already resolved name for this GRF (another server has sent the
 
				 * name of the GRF already */
 
				AddGRFTextToList(&c->name, FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true));
 
				c->name->Release();
 
				c->name = FindUnknownGRFName(c->ident.grfid, c->ident.md5sum, true);
 
				c->name->AddRef();
 
				c->status = GCS_NOT_FOUND;
 

	
 
				/* If we miss a file, we're obviously incompatible */
 
				item->info.compatible = false;
 
			} else {
 
				c->filename  = f->filename;
 
				CleanUpGRFText(c->name);
 
				c->name      = DuplicateGRFText(f->name);
 
				c->info      = f->info;
 
				c->status    = GCS_UNKNOWN;
 
				c->filename = f->filename;
 
				c->name->Release();
 
				c->name = f->name;
 
				c->name->AddRef();
 
				c->info->Release();
 
				c->info = f->info;
 
				c->info->AddRef();
 
				c->status = GCS_UNKNOWN;
 
			}
 
		}
 
	}
 

	
 
	InvalidateWindowClassesData(WC_NETWORK_WINDOW);
 
}
src/network/network_udp.cpp
Show inline comments
 
@@ -366,47 +366,52 @@ DEF_UDP_RECEIVE_COMMAND(Client, PACKET_U
 
	DEBUG(net, 6, "[udp] newgrf data reply from %s", client_addr->GetAddressAsString());
 

	
 
	num_grfs = p->Recv_uint8 ();
 
	if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
 

	
 
	for (i = 0; i < num_grfs; i++) {
 
		char *unknown_name;
 
		char name[NETWORK_GRF_NAME_LENGTH];
 
		GRFIdentifier c;
 

	
 
		this->ReceiveGRFIdentifier(p, &c);
 
		p->Recv_string(name, sizeof(name));
 

	
 
		/* An empty name is not possible under normal circumstances
 
		 * and causes problems when showing the NewGRF list. */
 
		if (StrEmpty(name)) continue;
 

	
 
		/* Finds the fake GRFConfig for the just read GRF ID and MD5sum tuple.
 
		/* Try to find the GRFTextWrapper for the name of this GRF ID and MD5sum tuple.
 
		 * If it exists and not resolved yet, then name of the fake GRF is
 
		 * overwritten with the name from the reply. */
 
		unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
 
		if (unknown_name != NULL && strcmp(unknown_name, UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
 
			ttd_strlcpy(unknown_name, name, NETWORK_GRF_NAME_LENGTH);
 
		GRFTextWrapper *unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
 
		if (unknown_name != NULL && strcmp(GetGRFStringFromGRFText(unknown_name->text), UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
 
			AddGRFTextToList(&unknown_name->text, name);
 
		}
 
	}
 
}
 

	
 
void ClientNetworkUDPSocketHandler::HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config)
 
{
 
	/* Find the matching GRF file */
 
	const GRFConfig *f = FindGRFConfig(config->ident.grfid, FGCM_EXACT, config->ident.md5sum);
 
	if (f == NULL) {
 
		/* Don't know the GRF, so mark game incompatible and the (possibly)
 
		 * already resolved name for this GRF (another server has sent the
 
		 * name of the GRF already */
 
		AddGRFTextToList(&config->name, FindUnknownGRFName(config->ident.grfid, config->ident.md5sum, true));
 
		config->name->Release();
 
		config->name = FindUnknownGRFName(config->ident.grfid, config->ident.md5sum, true);
 
		config->name->AddRef();
 
		config->status = GCS_NOT_FOUND;
 
	} else {
 
		config->filename  = f->filename;
 
		config->name      = DuplicateGRFText(f->name);
 
		config->info      = f->info;
 
		config->filename = f->filename;
 
		config->name->Release();
 
		config->name = f->name;
 
		config->name->AddRef();
 
		config->info->Release();
 
		config->info = f->info;
 
		config->info->AddRef();
 
	}
 
	SetBit(config->flags, GCF_COPY);
 
}
 

	
 
/* Broadcast to all ips */
 
static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
src/newgrf.cpp
Show inline comments
 
@@ -5379,17 +5379,17 @@ static void ScanInfo(ByteReader *buf)
 
		DEBUG(grf, 0, "%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur_grfconfig->filename, name, BSWAP32(grfid), grf_version);
 
	}
 

	
 
	/* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
 
	if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
 

	
 
	AddGRFTextToList(&_cur_grfconfig->name, 0x7F, grfid, name);
 
	AddGRFTextToList(&_cur_grfconfig->name->text, 0x7F, grfid, name);
 

	
 
	if (buf->HasData()) {
 
		const char *info = buf->ReadString();
 
		AddGRFTextToList(&_cur_grfconfig->info, 0x7F, grfid, info);
 
		AddGRFTextToList(&_cur_grfconfig->info->text, 0x7F, grfid, info);
 
	}
 

	
 
	/* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
 
	_skip_sprites = -1;
 
}
 

	
 
@@ -6463,20 +6463,20 @@ static void TranslateGRFStrings(ByteRead
 
	}
 
}
 

	
 
/** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
 
static bool ChangeGRFName(byte langid, const char *str)
 
{
 
	AddGRFTextToList(&_cur_grfconfig->name, langid, _cur_grfconfig->ident.grfid, str);
 
	AddGRFTextToList(&_cur_grfconfig->name->text, langid, _cur_grfconfig->ident.grfid, str);
 
	return true;
 
}
 

	
 
/** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
 
static bool ChangeGRFDescription(byte langid, const char *str)
 
{
 
	AddGRFTextToList(&_cur_grfconfig->info, langid, _cur_grfconfig->ident.grfid, str);
 
	AddGRFTextToList(&_cur_grfconfig->info->text, langid, _cur_grfconfig->ident.grfid, str);
 
	return true;
 
}
 

	
 
/** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
 
static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
 
{
src/newgrf_config.cpp
Show inline comments
 
@@ -18,30 +18,48 @@
 
#include "newgrf_text.h"
 
#include "window_func.h"
 

	
 
#include "fileio_func.h"
 
#include "fios.h"
 

	
 
/** Create a new GRFTextWrapper. */
 
GRFTextWrapper::GRFTextWrapper() :
 
	text(NULL)
 
{
 
}
 

	
 
/** Cleanup a GRFTextWrapper object. */
 
GRFTextWrapper::~GRFTextWrapper()
 
{
 
	CleanUpGRFText(this->text);
 
}
 

	
 
/**
 
 * Create a new GRFConfig.
 
 * @param filename Set the filename of this GRFConfig to filename. The argument
 
 *   is copied so the original string isn't needed after the constructor.
 
 */
 
GRFConfig::GRFConfig(const char *filename) :
 
	name(new GRFTextWrapper()),
 
	info(new GRFTextWrapper()),
 
	num_valid_params(lengthof(param))
 
{
 
	if (filename != NULL) this->filename = strdup(filename);
 
	this->name->AddRef();
 
	this->info->AddRef();
 
}
 

	
 
/**
 
 * Create a new GRFConfig that is a deep copy of an existing config.
 
 * @param config The GRFConfig object to make a copy of.
 
 */
 
GRFConfig::GRFConfig(const GRFConfig &config) :
 
	ZeroedMemoryAllocator(),
 
	ident(config.ident),
 
	name(config.name),
 
	info(config.info),
 
	version(config.version),
 
	min_loadable_version(config.min_loadable_version),
 
	flags(config.flags & ~(1 << GCF_COPY)),
 
	status(config.status),
 
	grf_bugs(config.grf_bugs),
 
	num_params(config.num_params),
 
@@ -49,14 +67,14 @@ GRFConfig::GRFConfig(const GRFConfig &co
 
	palette(config.palette),
 
	has_param_defaults(config.has_param_defaults)
 
{
 
	MemCpyT<uint8>(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum));
 
	MemCpyT<uint32>(this->param, config.param, lengthof(this->param));
 
	if (config.filename != NULL) this->filename = strdup(config.filename);
 
	this->name = DuplicateGRFText(config.name);
 
	this->info = DuplicateGRFText(config.info);
 
	this->name->AddRef();
 
	this->info->AddRef();
 
	if (config.error    != NULL) this->error    = new GRFError(*config.error);
 
	for (uint i = 0; i < config.param_info.Length(); i++) {
 
		if (config.param_info[i] == NULL) {
 
			*this->param_info.Append() = NULL;
 
		} else {
 
			*this->param_info.Append() = new GRFParameterInfo(*config.param_info[i]);
 
@@ -64,41 +82,41 @@ GRFConfig::GRFConfig(const GRFConfig &co
 
	}
 
}
 

	
 
/** Cleanup a GRFConfig object. */
 
GRFConfig::~GRFConfig()
 
{
 
	/* GCF_COPY as in NOT strdupped/alloced the filename and info */
 
	/* GCF_COPY as in NOT strdupped/alloced the filename */
 
	if (!HasBit(this->flags, GCF_COPY)) {
 
		free(this->filename);
 
		CleanUpGRFText(this->info);
 
		delete this->error;
 
	}
 
	CleanUpGRFText(this->name);
 
	this->name->Release();
 
	this->info->Release();
 

	
 
	for (uint i = 0; i < this->param_info.Length(); i++) delete this->param_info[i];
 
}
 

	
 
/**
 
 * Get the name of this grf. In case the name isn't known
 
 * the filename is returned.
 
 * @return The name of filename of this grf.
 
 */
 
const char *GRFConfig::GetName() const
 
{
 
	const char *name = GetGRFStringFromGRFText(this->name);
 
	const char *name = GetGRFStringFromGRFText(this->name->text);
 
	return StrEmpty(name) ? this->filename : name;
 
}
 

	
 
/**
 
 * Get the grf info.
 
 * @return A string with a description of this grf.
 
 */
 
const char *GRFConfig::GetDescription() const
 
{
 
	return GetGRFStringFromGRFText(this->info);
 
	return GetGRFStringFromGRFText(this->info->text);
 
}
 

	
 
/** Set the default value for all parameters as specified by action14. */
 
void GRFConfig::SetParameterDefaults()
 
{
 
	this->num_params = 0;
 
@@ -479,14 +497,18 @@ compatible_grf:
 
			 * When the GCF_COPY flag is set, it is certain that the filename is
 
			 * already a local one, so there is no need to replace it. */
 
			if (!HasBit(c->flags, GCF_COPY)) {
 
				free(c->filename);
 
				c->filename = strdup(f->filename);
 
				memcpy(c->ident.md5sum, f->ident.md5sum, sizeof(c->ident.md5sum));
 
				if (c->name == NULL) c->name = DuplicateGRFText(f->name);
 
				if (c->info == NULL) c->info = DuplicateGRFText(f->info);
 
				c->name->Release();
 
				c->name = f->name;
 
				c->name->AddRef();
 
				c->info->Release();
 
				c->info = f->name;
 
				c->info->AddRef();
 
				c->error = NULL;
 
				c->version = f->version;
 
				c->min_loadable_version = f->min_loadable_version;
 
				c->num_valid_params = f->num_valid_params;
 
				c->has_param_defaults = f->has_param_defaults;
 
				for (uint i = 0; i < f->param_info.Length(); i++) {
 
@@ -643,13 +665,13 @@ const GRFConfig *FindGRFConfig(uint32 gr
 

	
 
#ifdef ENABLE_NETWORK
 

	
 
/** Structure for UnknownGRFs; this is a lightweight variant of GRFConfig */
 
struct UnknownGRF : public GRFIdentifier {
 
	UnknownGRF *next;
 
	char   name[NETWORK_GRF_NAME_LENGTH];
 
	GRFTextWrapper *name;
 
};
 

	
 
/**
 
 * Finds the name of a NewGRF in the list of names for unknown GRFs. An
 
 * unknown GRF is a GRF where the .grf is not found during scanning.
 
 *
 
@@ -659,17 +681,17 @@ struct UnknownGRF : public GRFIdentifier
 
 * up the GRF anyway and that works better with the GRF ID.
 
 *
 
 * @param grfid  the GRF ID part of the 'unique' GRF identifier
 
 * @param md5sum the MD5 checksum part of the 'unique' GRF identifier
 
 * @param create whether to create a new GRFConfig if the GRFConfig did not
 
 *               exist in the fake list of GRFConfigs.
 
 * @return the GRFConfig with the given GRF ID and MD5 checksum or NULL when
 
 *         it does not exist and create is false. This value must NEVER be
 
 *         freed by the caller.
 
 * @return The GRFTextWrapper of the name of the GRFConfig with the given GRF ID
 
 *         and MD5 checksum or NULL when it does not exist and create is false.
 
 *         This value must NEVER be freed by the caller.
 
 */
 
char *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create)
 
GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create)
 
{
 
	UnknownGRF *grf;
 
	static UnknownGRF *unknown_grfs = NULL;
 

	
 
	for (grf = unknown_grfs; grf != NULL; grf = grf->next) {
 
		if (grf->grfid == grfid) {
 
@@ -679,13 +701,16 @@ char *FindUnknownGRFName(uint32 grfid, u
 

	
 
	if (!create) return NULL;
 

	
 
	grf = CallocT<UnknownGRF>(1);
 
	grf->grfid = grfid;
 
	grf->next  = unknown_grfs;
 
	strecpy(grf->name, UNKNOWN_GRF_NAME_PLACEHOLDER, lastof(grf->name));
 
	grf->name = new GRFTextWrapper();
 
	grf->name->AddRef();
 

	
 
	AddGRFTextToList(&grf->name->text, UNKNOWN_GRF_NAME_PLACEHOLDER);
 
	memcpy(grf->md5sum, md5sum, sizeof(grf->md5sum));
 

	
 
	unknown_grfs = grf;
 
	return grf->name;
 
}
 

	
src/newgrf_config.h
Show inline comments
 
@@ -12,12 +12,13 @@
 
#ifndef NEWGRF_CONFIG_H
 
#define NEWGRF_CONFIG_H
 

	
 
#include "strings_type.h"
 
#include "core/alloc_type.hpp"
 
#include "core/smallmap_type.hpp"
 
#include "misc/countedptr.hpp"
 

	
 
/** GRF config bit flags */
 
enum GCF_Flags {
 
	GCF_SYSTEM,     ///< GRF file is an openttd-internal system grf
 
	GCF_UNSAFE,     ///< GRF file is unsafe for static usage
 
	GCF_STATIC,     ///< GRF file is used statically (can be used in any MP game)
 
@@ -126,23 +127,31 @@ struct GRFParameterInfo {
 
	SmallMap<uint32, struct GRFText *, 8> value_names; ///< Names for each value.
 

	
 
	uint32 GetValue(struct GRFConfig *config) const;
 
	void SetValue(struct GRFConfig *config, uint32 value);
 
};
 

	
 
/** Reference counted wrapper around a GRFText pointer. */
 
struct GRFTextWrapper : public SimpleCountedObject {
 
	struct GRFText *text; ///< The actual text
 

	
 
	GRFTextWrapper();
 
	~GRFTextWrapper();
 
};
 

	
 
/** Information about GRF, used in the game and (part of it) in savegames */
 
struct GRFConfig : ZeroedMemoryAllocator {
 
	GRFConfig(const char *filename = NULL);
 
	GRFConfig(const GRFConfig &config);
 
	~GRFConfig();
 

	
 
	GRFIdentifier ident;                           ///< grfid and md5sum to uniquely identify newgrfs
 
	uint8 original_md5sum[16];                     ///< MD5 checksum of original file if only a 'compatible' file was loaded
 
	char *filename;                                ///< Filename - either with or without full path
 
	struct GRFText *name;                          ///< NOSAVE: GRF name (Action 0x08)
 
	struct GRFText *info;                          ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
 
	GRFTextWrapper *name;                          ///< NOSAVE: GRF name (Action 0x08)
 
	GRFTextWrapper *info;                          ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
 
	GRFError *error;                               ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B)
 

	
 
	uint32 version;                                ///< NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown
 
	uint32 min_loadable_version;                   ///< NOSAVE: Minimum compatible version a NewGRF can define
 
	uint8 flags;                                   ///< NOSAVE: GCF_Flags, bitset
 
	GRFStatus status;                              ///< NOSAVE: GRFStatus, enum
 
@@ -195,10 +204,10 @@ char *GRFBuildParamList(char *dst, const
 
/* In newgrf_gui.cpp */
 
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config);
 

	
 
#ifdef ENABLE_NETWORK
 
/* For communication about GRFs over the network */
 
#define UNKNOWN_GRF_NAME_PLACEHOLDER "<Unknown>"
 
char *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create);
 
GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create);
 
#endif /* ENABLE_NETWORK */
 

	
 
#endif /* NEWGRF_CONFIG_H */
0 comments (0 inline, 0 general)