|
|
/* $Id$ */
|
|
|
|
|
|
/*
|
|
|
* This file is part of OpenTTD.
|
|
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
|
*/
|
|
|
|
|
|
/** @file script_scanner.cpp Allows scanning for scripts. */
|
|
|
|
|
|
#include "../stdafx.h"
|
|
|
#include "../debug.h"
|
|
|
#include "../string_func.h"
|
|
|
#include "../settings_type.h"
|
|
|
|
|
|
#include "../script/squirrel.hpp"
|
|
|
#include "script_scanner.hpp"
|
|
|
#include "script_info.hpp"
|
|
|
|
|
|
#if defined(ENABLE_NETWORK)
|
|
|
#include "../network/network_content.h"
|
|
|
#include "../3rdparty/md5/md5.h"
|
|
|
#include "../tar_type.h"
|
|
|
#endif /* ENABLE_NETWORK */
|
|
|
|
|
|
#include "../safeguards.h"
|
|
|
|
|
|
bool ScriptScanner::AddFile(const char *filename, size_t basepath_length, const char *tar_filename)
|
|
|
{
|
|
|
free(this->main_script);
|
|
|
this->main_script = stredup(filename);
|
|
|
if (this->main_script == NULL) return false;
|
|
|
|
|
|
free(this->tar_file);
|
|
|
if (tar_filename != NULL) {
|
|
|
this->tar_file = stredup(tar_filename);
|
|
|
if (this->tar_file == NULL) return false;
|
|
|
} else {
|
|
|
this->tar_file = NULL;
|
|
|
}
|
|
|
|
|
|
const char *end = this->main_script + strlen(this->main_script) + 1;
|
|
|
char *p = strrchr(this->main_script, PATHSEPCHAR);
|
|
|
if (p == NULL) {
|
|
|
p = this->main_script;
|
|
|
} else {
|
|
|
/* Skip over the path separator character. We don't need that. */
|
|
|
p++;
|
|
@@ -159,50 +157,48 @@ void ScriptScanner::RegisterScript(Scrip
|
|
|
/* Add the script to the 'unique' script list, where only the highest version
|
|
|
* of the script is registered. */
|
|
|
if (this->info_single_list.find(script_original_name) == this->info_single_list.end()) {
|
|
|
this->info_single_list[stredup(script_original_name)] = info;
|
|
|
} else if (this->info_single_list[script_original_name]->GetVersion() < info->GetVersion()) {
|
|
|
this->info_single_list[script_original_name] = info;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
char *ScriptScanner::GetConsoleList(char *p, const char *last, bool newest_only) const
|
|
|
{
|
|
|
p += seprintf(p, last, "List of %s:\n", this->GetScannerName());
|
|
|
const ScriptInfoList &list = newest_only ? this->info_single_list : this->info_list;
|
|
|
ScriptInfoList::const_iterator it = list.begin();
|
|
|
for (; it != list.end(); it++) {
|
|
|
ScriptInfo *i = (*it).second;
|
|
|
p += seprintf(p, last, "%10s (v%d): %s\n", i->GetName(), i->GetVersion(), i->GetDescription());
|
|
|
}
|
|
|
p += seprintf(p, last, "\n");
|
|
|
|
|
|
return p;
|
|
|
}
|
|
|
|
|
|
#if defined(ENABLE_NETWORK)
|
|
|
|
|
|
/** Helper for creating a MD5sum of all files within of a script. */
|
|
|
struct ScriptFileChecksumCreator : FileScanner {
|
|
|
byte md5sum[16]; ///< The final md5sum.
|
|
|
Subdirectory dir; ///< The directory to look in.
|
|
|
|
|
|
/**
|
|
|
* Initialise the md5sum to be all zeroes,
|
|
|
* so we can easily xor the data.
|
|
|
*/
|
|
|
ScriptFileChecksumCreator(Subdirectory dir)
|
|
|
{
|
|
|
this->dir = dir;
|
|
|
memset(this->md5sum, 0, sizeof(this->md5sum));
|
|
|
}
|
|
|
|
|
|
/* Add the file and calculate the md5 sum. */
|
|
|
virtual bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename)
|
|
|
{
|
|
|
Md5 checksum;
|
|
|
uint8 buffer[1024];
|
|
|
size_t len, size;
|
|
|
byte tmp_md5sum[16];
|
|
|
|
|
|
/* Open the file ... */
|
|
@@ -266,26 +262,24 @@ static bool IsSameScript(const ContentIn
|
|
|
* main script name as the search algorithm requires the main script to
|
|
|
* be in a subdirectory of the script directory; so <dir>/<path>/main.nut. */
|
|
|
*strrchr(path, PATHSEPCHAR) = '\0';
|
|
|
checksum.Scan(".nut", path);
|
|
|
}
|
|
|
|
|
|
return memcmp(ci->md5sum, checksum.md5sum, sizeof(ci->md5sum)) == 0;
|
|
|
}
|
|
|
|
|
|
bool ScriptScanner::HasScript(const ContentInfo *ci, bool md5sum)
|
|
|
{
|
|
|
for (ScriptInfoList::iterator it = this->info_list.begin(); it != this->info_list.end(); it++) {
|
|
|
if (IsSameScript(ci, md5sum, (*it).second, this->GetDirectory())) return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
const char *ScriptScanner::FindMainScript(const ContentInfo *ci, bool md5sum)
|
|
|
{
|
|
|
for (ScriptInfoList::iterator it = this->info_list.begin(); it != this->info_list.end(); it++) {
|
|
|
if (IsSameScript(ci, md5sum, (*it).second, this->GetDirectory())) return (*it).second->GetMainScript();
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
#endif /* ENABLE_NETWORK */
|