more commands to manage zipped mod packages
addzipmod zipname Add the zip package file "mods/zipname.zip" to the virtual file system. Only files below the path "packages/" are added (and also files below "config/", if zipname starts with "###"). If the size of the zip file is below zipcachemaxsize, the whole zip file is cached in memory. (Un-cached zip files are kept open at all time, so caching keeps the number of simultaneously opened files lower.) zipmodremove zipname Removes one zip file from the virtual file system. zipmodclear Removes all zip files from the virtual file system. zipmodlist [what] Lists zip files in "mods/". By default, or if "what" is "all", all zips are listed. If "what" is "active", only those zips, that are already in use, are listed. If "what" is "inactive", only the unused zip files are listed. zipmodgetdesc zipfile Reads and returns the first 11 lines from the file "desc.txt" in the named zip file. The first line is supposed to contain a descriptive title for the zip (for use in menus) and the next 10 lines should contain a more detailed description (also for use in menus). The command also unpacks "preview.jpg" from the zip and mounts it as a temporary file under the name "packages/modpreviews/zipname.jpg". zipmodgetfiles zipfile Returns the list of files contained in a zip file. zipmodgetrevision zipfile Returns the revision number of the zip file. The number is supposed to be part of a filename: "revision_n". If no such file is found in the zip file, the return value is zero. The content of the revision file is not relevant and a file size of zero is recommended. DOCREF addzipmod zipmodremove zipmodclear zipcachemaxsize DOCREF zipmodlist zipmodgetdesc zipmodgetfiles zipmodgetrevision
This commit is contained in:
+149
-4
@@ -477,8 +477,6 @@ void listmemfiles()
|
||||
COMMAND(listmemfiles, "");
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// manage zipped mod packages in subdirectory "mods/" including description and preview images
|
||||
// zip packages are restricted to contain files below "packages/" only - unless the zip filename starts with "###", which additionally allows files below "config/"
|
||||
|
||||
@@ -488,8 +486,6 @@ ziparchive *findzip(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef STANDALONE
|
||||
|
||||
const char *fixzipname(char *name) // check, if valid path + filename, based on mods/, return NULL if invalid
|
||||
{
|
||||
string tmp;
|
||||
@@ -556,6 +552,155 @@ void addzipmod(char *name)
|
||||
}
|
||||
COMMAND(addzipmod, "s");
|
||||
|
||||
void zipmodremove(char *name)
|
||||
{
|
||||
const char *pname = fixzipname(name);
|
||||
ziparchive *exists = pname ? findzip(name) : NULL;
|
||||
if(!exists)
|
||||
{
|
||||
conoutf("zip %s is not loaded", name);
|
||||
return;
|
||||
}
|
||||
if(exists->openfiles)
|
||||
{
|
||||
conoutf("zip %s has %d open files", name, exists->openfiles);
|
||||
return;
|
||||
}
|
||||
conoutf("removed zip %s", exists->name);
|
||||
archives.removeobj(exists);
|
||||
rebuildzipfilehashtable();
|
||||
delete exists;
|
||||
}
|
||||
COMMAND(zipmodremove, "s");
|
||||
|
||||
void zipmodclear()
|
||||
{
|
||||
loopvrev(archives)
|
||||
{
|
||||
ziparchive *a = archives[i];
|
||||
if(a->openfiles)
|
||||
{
|
||||
conoutf("zip %s has %d open files", a->name, a->openfiles);
|
||||
continue;
|
||||
}
|
||||
delete archives.remove(i);
|
||||
}
|
||||
rebuildzipfilehashtable();
|
||||
}
|
||||
COMMAND(zipmodclear, "");
|
||||
|
||||
void zipmodlist(char *which) // "active", "inactive", "all"(default)
|
||||
{
|
||||
vector<char> res;
|
||||
if(!strcasecmp(which, "active"))
|
||||
{
|
||||
loopv(archives) cvecprintf(res, "%s ", archives[i]->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool inactive = !strcasecmp(which, "inactive");
|
||||
vector<char *> files;
|
||||
listfilesrecursive("mods", files);
|
||||
files.sort(stringsort);
|
||||
loopvrev(files) if(files.inrange(i + 1) && !strcmp(files[i], files[i + 1])) delstring(files.remove(i + 1)); // remove doubles
|
||||
loopv(files)
|
||||
{
|
||||
char *f = files[i];
|
||||
if(!strncmp(f, "mods/", 5) && !strncmp(f + strlen(f) - 4, ".zip", 4))
|
||||
{
|
||||
f += 5;
|
||||
f[strlen(f) - 4] = '\0';
|
||||
if(fixzipname(f) && (!inactive || !findzip(f))) cvecprintf(res, "%s ", f);
|
||||
}
|
||||
}
|
||||
files.deletearrays();
|
||||
}
|
||||
if(res.length()) res.last() = '\0';
|
||||
else res.add('\0');
|
||||
result(res.getbuf());
|
||||
}
|
||||
COMMAND(zipmodlist, "s");
|
||||
|
||||
const char *desctxt = "desc.txt", *previewjpg = "preview.jpg", *modrev = "revision_"; // special files in zip containing description or preview
|
||||
|
||||
void zipmodgetdesc(char *name) // open zip, read desc.txt and mount preview picture
|
||||
{
|
||||
const char *pname = fixzipname(name);
|
||||
stream *f = pname ? openfile(pname, "rb") : NULL, *zf = NULL;
|
||||
vector<const char *> files;
|
||||
vector<char> res;
|
||||
void *mz = zipmanualopen(f, files);
|
||||
string tmp;
|
||||
if(!f || !mz) conoutf("failed to read/open zip file %s", pname);
|
||||
else
|
||||
{
|
||||
loopv(files)
|
||||
{
|
||||
if(!strcmp(files[i], desctxt))
|
||||
{
|
||||
if((zf = zipmanualstream(mz, i))) loopk(11)
|
||||
{
|
||||
zf->getline(tmp, MAXSTRLEN / 2);
|
||||
filtertext(tmp, tmp, FTXT__ZIPDESC);
|
||||
if(*tmp) cvecprintf(res, "%s\n", escapestring(tmp));
|
||||
else break;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(files[i], previewjpg))
|
||||
{
|
||||
vector<uchar> *v = new vector<uchar>;
|
||||
zf = openvecfile(v);
|
||||
int got = zipmanualread(mz, i, zf, 128 * 1024); // max. file size for preview.jpg is 128k
|
||||
formatstring(tmp)("packages/modpreviews/%s.jpg", name);
|
||||
addmemfile(tmp, v->getbuf(), got);
|
||||
if(got == 128 * 1024) conoutf("\f3preview.jpg in zip file %s exceeds maximum file size: file truncated", pname);
|
||||
}
|
||||
DELETEP(zf);
|
||||
}
|
||||
zipmanualclose(mz);
|
||||
}
|
||||
if(res.length()) res.last() = '\0';
|
||||
else res.add('\0');
|
||||
result(res.getbuf());
|
||||
}
|
||||
COMMAND(zipmodgetdesc, "s");
|
||||
|
||||
void zipmodgetfiles(char *name) // open zip, read list of files
|
||||
{
|
||||
const char *pname = fixzipname(name);
|
||||
stream *f = pname ? openfile(pname, "rb") : NULL;
|
||||
vector<const char *> files;
|
||||
vector<char> res;
|
||||
void *mz = zipmanualopen(f, files);
|
||||
if(!f || !mz) conoutf("failed to read/open zip file %s", pname);
|
||||
else
|
||||
{
|
||||
loopv(files) cvecprintf(res, "%s\n", escapestring(files[i]));
|
||||
zipmanualclose(mz);
|
||||
}
|
||||
if(res.length()) res.last() = '\0';
|
||||
else res.add('\0');
|
||||
result(res.getbuf());
|
||||
}
|
||||
COMMAND(zipmodgetfiles, "s");
|
||||
|
||||
void zipmodgetrevision(char *name) // open zip, read list of files
|
||||
{
|
||||
const char *pname = fixzipname(name);
|
||||
stream *f = pname ? openfile(pname, "rb") : NULL;
|
||||
vector<const char *> files;
|
||||
int res = 0, modrevlen = (int)strlen(modrev);
|
||||
void *mz = zipmanualopen(f, files);
|
||||
if(!f || !mz) conoutf("failed to read/open zip file %s", pname);
|
||||
else
|
||||
{
|
||||
loopv(files) if(!strncasecmp(files[i], modrev, modrevlen)) res = atoi(files[i] + modrevlen);
|
||||
zipmanualclose(mz);
|
||||
}
|
||||
intret(res);
|
||||
}
|
||||
COMMAND(zipmodgetrevision, "s");
|
||||
|
||||
void writezipmodconfig(stream *f)
|
||||
{
|
||||
f->printf("zipcachemaxsize %d\n", zipcachemaxsize);
|
||||
|
||||
Reference in New Issue
Block a user