Changeset - r11278:28e3268b0f53
[Not reviewed]
master
0 3 0
rubidium - 15 years ago 2009-03-06 19:33:45
rubidium@openttd.org
(svn r15632) -Feature: allow downloading scenarios and heightmaps via bananas.
3 files changed with 126 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/fios.cpp
Show inline comments
 
@@ -495,3 +495,114 @@ void FiosGetHeightmapList(SaveLoadDialog
 

	
 
	FiosGetFileList(mode, &FiosGetHeightmapListCallback, strcmp(base_path, _fios_path) == 0 ? HEIGHTMAP_DIR : NO_DIRECTORY);
 
}
 

	
 
#if defined(ENABLE_NETWORK)
 
#include "core/smallvec_type.hpp"
 
#include "network/network_content.h"
 
#include "md5.h"
 

	
 
/** Basic data to distinguish a scenario. Used in the server list window */
 
struct ScenarioIdentifier {
 
	uint32 scenid;    ///< ID for the scenario (generated by content)
 
	uint8 md5sum[16]; ///< MD5 checksum of file
 

	
 
	bool operator == (const ScenarioIdentifier &other) const
 
	{
 
		return this->scenid == other.scenid &&
 
				memcmp(this->md5sum, other.md5sum, sizeof(this->md5sum)) == 0;
 
	}
 

	
 
	bool operator != (const ScenarioIdentifier &other) const
 
	{
 
		return !(*this == other);
 
	}
 
};
 

	
 
/**
 
 * Scanner to find the unique IDs of scenarios
 
 */
 
class ScenarioScanner : protected FileScanner, public SmallVector<ScenarioIdentifier, 8> {
 
	bool scanned; ///< Whether we've already scanned
 
public:
 
	/** Initialise */
 
	ScenarioScanner() : scanned(false) {}
 

	
 
	/**
 
	 * Scan, but only if it's needed.
 
	 * @param rescan whether to force scanning even when it's not necessary
 
	 */
 
	void Scan(bool rescan)
 
	{
 
		if (this->scanned && !rescan) return;
 

	
 
		this->FileScanner::Scan(".id", SCENARIO_DIR, true, true);
 
		this->scanned = true;
 
	}
 

	
 
	/* virtual */ bool AddFile(const char *filename, size_t basepath_length)
 
	{
 
		FILE *f = FioFOpenFile(filename, "r");
 
		if (f == NULL) return false;
 

	
 
		ScenarioIdentifier id;
 
		fscanf(f, "%i", &id.scenid);
 
		FioFCloseFile(f);
 

	
 
		Md5 checksum;
 
		uint8 buffer[1024];
 
		size_t len, size;
 

	
 
		/* open the scenario file, but first get the name.
 
		 * This is safe as we check on extension which
 
		 * must always exist. */
 
		*strrchr(filename, '.') = '\0';
 
		f = FioFOpenFile(filename, "rb", SCENARIO_DIR, &size);
 
		if (f == NULL) return false;
 

	
 
		/* calculate md5sum */
 
		while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, f)) != 0 && size != 0) {
 
			size -= len;
 
			checksum.Append(buffer, len);
 
		}
 
		checksum.Finish(id.md5sum);
 

	
 
		FioFCloseFile(f);
 

	
 
		this->Include(id);
 
		return true;
 
	}
 
};
 

	
 
/** Scanner for scenarios */
 
static ScenarioScanner _scanner;
 

	
 
/**
 
 * Check whether we've got a given scenario based on it's unique ID.
 
 * @param ci the content info to compare it to
 
 * @param md5sum whether to look at the md5sum or the id
 
 * @return true if we've got the scenario
 
 */
 
bool HasScenario(const ContentInfo *ci, bool md5sum)
 
{
 
	_scanner.Scan(false);
 

	
 
	for (ScenarioIdentifier *id = _scanner.Begin(); id != _scanner.End(); id++) {
 
		if (md5sum ?
 
				(memcmp(id->md5sum, ci->md5sum, sizeof(id->md5sum)) == 0) :
 
				(id->scenid == ci->unique_id)) {
 
			return true;
 
		}
 
	}
 

	
 
	return false;
 
}
 

	
 
/**
 
 * Force a (re)scan of the scenarios.
 
 */
 
void ScanScenarios()
 
{
 
	_scanner.Scan(true);
 
}
 

	
 
#endif /* ENABLE_NETWORK */
src/network/network_content.cpp
Show inline comments
 
@@ -22,6 +22,7 @@
 

	
 
extern bool TarListAddFile(const char *filename);
 
extern bool HasGraphicsSet(const ContentInfo *ci, bool md5sum);
 
extern bool HasScenario(const ContentInfo *ci, bool md5sum);
 
ClientNetworkContentSocketHandler _network_content_client;
 

	
 
/** Wrapper function for the HasProc */
 
@@ -86,6 +87,11 @@ DEF_CONTENT_RECEIVE_COMMAND(Client, PACK
 
			proc = AI::HasAI; break;
 
			break;
 

	
 
		case CONTENT_TYPE_SCENARIO:
 
		case CONTENT_TYPE_HEIGHTMAP:
 
			proc = HasScenario;
 
			break;
 

	
 
		default:
 
			break;
 
	}
 
@@ -143,6 +149,8 @@ void ClientNetworkContentSocketHandler::
 
{
 
	if (type == CONTENT_TYPE_END) {
 
		this->RequestContentList(CONTENT_TYPE_BASE_GRAPHICS);
 
		this->RequestContentList(CONTENT_TYPE_SCENARIO);
 
		this->RequestContentList(CONTENT_TYPE_HEIGHTMAP);
 
		this->RequestContentList(CONTENT_TYPE_AI);
 
		this->RequestContentList(CONTENT_TYPE_NEWGRF);
 
		this->RequestContentList(CONTENT_TYPE_AI_LIBRARY);
src/network/network_content_gui.cpp
Show inline comments
 
@@ -98,6 +98,13 @@ public:
 
					InvalidateWindowData(WC_NETWORK_WINDOW, 0, 2);
 
					break;
 

	
 
				case CONTENT_TYPE_SCENARIO:
 
				case CONTENT_TYPE_HEIGHTMAP:
 
					InvalidateWindowClasses(WC_SAVELOAD);
 
					extern void ScanScenarios();
 
					ScanScenarios();
 
					break;
 

	
 
				default:
 
					break;
 
			}
0 comments (0 inline, 0 general)