changeset 14681:86939658ba6b draft

(svn r19262) -Feature: finalise BaNaNaS support for music sets
author rubidium <rubidium@openttd.org>
date Fri, 26 Feb 2010 00:00:55 +0000
parents f3dfa0c1c278
children aa3e0d8fcf57
files src/base_media_base.h src/fileio.cpp src/fileio_func.h src/network/network_content.cpp src/network/network_content_gui.cpp
diffstat 5 files changed, 88 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/base_media_base.h
+++ b/src/base_media_base.h
@@ -170,7 +170,9 @@
 	static uint FindSets()
 	{
 		BaseMedia<Tbase_set> fs;
-		return fs.Scan(GetExtension(), Tbase_set::SUBDIR);
+		/* GM_DIR == music set. Music sets don't support tars,
+		 * so there is no need to search for tars in that case. */
+		return fs.Scan(GetExtension(), Tbase_set::SUBDIR, Tbase_set::SUBDIR != GM_DIR);
 	}
 
 	/**
--- a/src/fileio.cpp
+++ b/src/fileio.cpp
@@ -743,6 +743,79 @@
 	return true;
 }
 
+/**
+ * Extract the tar with the given filename in the directory
+ * where the tar resides.
+ * @param tar_filename the name of the tar to extract.
+ * @return false on failure.
+ */
+bool ExtractTar(const char *tar_filename)
+{
+	TarList::iterator it = _tar_list.find(tar_filename);
+	/* We don't know the file. */
+	if (it == _tar_list.end()) return false;
+
+	const char *dirname = (*it).second.dirname;
+
+	/* The file doesn't have a sub directory! */
+	if (dirname == NULL) return false;
+
+	char filename[MAX_PATH];
+	strecpy(filename, tar_filename, lastof(filename));
+	char *p = strrchr(filename, PATHSEPCHAR);
+	/* The file's path does not have a separator? */
+	if (p == NULL) return false;
+
+	p++;
+	strecpy(p, dirname, lastof(filename));
+	DEBUG(misc, 8, "Extracting %s to directory %s", tar_filename, filename);
+	FioCreateDirectory(filename);
+
+	for (TarFileList::iterator it2 = _tar_filelist.begin(); it2 != _tar_filelist.end(); it2++) {
+		if (strcmp((*it2).second.tar_filename, tar_filename) != 0) continue;
+
+		strecpy(p, (*it2).first.c_str(), lastof(filename));
+
+		DEBUG(misc, 9, "  extracting %s", filename);
+
+		/* First open the file in the .tar. */
+		size_t to_copy = 0;
+		FILE *in = FioFOpenFileTar(&(*it2).second, &to_copy);
+		if (in == NULL) {
+			DEBUG(misc, 6, "Extracting %s failed; could not open %s", filename, tar_filename);
+			return false;
+		}
+
+		/* Now open the 'output' file. */
+		FILE *out = fopen(filename, "wb");
+		if (out == NULL) {
+			DEBUG(misc, 6, "Extracting %s failed; could not open %s", filename, filename);
+			fclose(in);
+			return false;
+		}
+
+		/* Now read from the tar and write it into the file. */
+		char buffer[4096];
+		size_t read;
+		for (; to_copy != 0; to_copy -= read) {
+			read = fread(buffer, 1, min(to_copy, lengthof(buffer)), in);
+			if (read <= 0 || fwrite(buffer, 1, read, out) != read) break;
+		}
+
+		/* Close everything up. */
+		fclose(in);
+		fclose(out);
+
+		if (to_copy != 0) {
+			DEBUG(misc, 6, "Extracting %s failed; still %i bytes to copy", filename, (int)to_copy);
+			return false;
+		}
+	}
+
+	DEBUG(misc, 9, "  extraction successful");
+	return true;
+}
+
 static int ScanPathForTarFiles(const char *path, size_t basepath_length)
 {
 	extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb);
--- a/src/fileio_func.h
+++ b/src/fileio_func.h
@@ -63,6 +63,7 @@
 bool FileExists(const char *filename);
 const char *FioTarFirstDir(const char *tarname);
 void FioTarAddLink(const char *src, const char *dest);
+bool ExtractTar(const char *tar_filename);
 
 extern char *_personal_dir; ///< custom directory for personal settings, saves, newgrf, etc.
 
--- a/src/network/network_content.cpp
+++ b/src/network/network_content.cpp
@@ -481,6 +481,12 @@
 
 		TarListAddFile(GetFullFilename(this->curInfo, false));
 
+		if (this->curInfo->type == CONTENT_TYPE_BASE_MUSIC) {
+			/* Music can't be in a tar. So extract the tar! */
+			ExtractTar(GetFullFilename(this->curInfo, false));
+			unlink(GetFullFilename(this->curInfo, false));
+		}
+
 		this->OnDownloadComplete(this->curInfo->id);
 	} else {
 		ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_EXTRACT, INVALID_STRING_ID, WL_ERROR);
--- a/src/network/network_content_gui.cpp
+++ b/src/network/network_content_gui.cpp
@@ -106,6 +106,11 @@
 					SetWindowDirty(WC_GAME_OPTIONS, 0);
 					break;
 
+				case CONTENT_TYPE_BASE_MUSIC:
+					BaseMusic::FindSets();
+					SetWindowDirty(WC_GAME_OPTIONS, 0);
+					break;
+
 				case CONTENT_TYPE_NEWGRF:
 					ScanNewGRFFiles();
 					/* Yes... these are the NewGRF windows */