(svn r15632) -Feature: allow downloading scenarios and heightmaps via bananas.

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
rubidium 15 years ago
parent bc58d4ef9a
commit 406832fed8

@ -495,3 +495,114 @@ void FiosGetHeightmapList(SaveLoadDialogMode mode)
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 */

@ -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, PACKET_CONTENT_SERVER_INFO)
proc = AI::HasAI; break;
break;
case CONTENT_TYPE_SCENARIO:
case CONTENT_TYPE_HEIGHTMAP:
proc = HasScenario;
break;
default:
break;
}
@ -143,6 +149,8 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentType type)
{
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);

@ -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;
}

Loading…
Cancel
Save