1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

- ZipArchive namespace for operations with zip archives, located in CZipLoader.h/cpp.

- new fields in mod format, for use with mod manager (check config/shemas/mod.json for details)
- removed some 0.92 compatibility from mods loading
- several compile fixes
This commit is contained in:
Ivan Savenko 2013-08-19 11:50:53 +00:00
parent 38c1542d9d
commit 5654fef901
15 changed files with 209 additions and 53 deletions

View File

@ -1612,7 +1612,7 @@ void VCAI::reserveObject(HeroPtr h, const CGObjectInstance *obj)
{
reservedObjs.push_back(obj);
reservedHeroesMap[h].push_back(obj);
logAi->debugStream() << "reserved object id=" << obj->id << "; address=" << (int)obj << "; name=" << obj->getHoverText();
logAi->debugStream() << "reserved object id=" << obj->id << "; address=" << (intptr_t)obj << "; name=" << obj->getHoverText();
}
void VCAI::validateVisitableObjs()

View File

@ -1,5 +1,8 @@
project(vcmi)
cmake_minimum_required(VERSION 2.6)
# TODO:
# 1) Detection of system version of minizip and use it instead of local
# 2) Detection of Qt5 and compilation of launcher, unless explicitly disabled
# where to look for cmake modules
set(CMAKE_MODULE_PATH ${CMAKE_HOME_DIRECTORY}/cmake_modules)
@ -16,6 +19,7 @@ set(VCMI_VERSION_PATCH 0)
option(ENABLE_ERM "Enable compilation of ERM scripting module" OFF)
option(ENABLE_EDITOR "Enable compilation of map editor" OFF)
option(ENABLE_LAUNCHER "Enable compilation of launcher" OFF)
option(ENABLE_TEST "Enable compilation of unit tests" OFF)
############################################
@ -52,11 +56,15 @@ find_package(SDL_mixer REQUIRED)
find_package(SDL_ttf REQUIRED)
find_package(ZLIB REQUIRED)
if (ENABLE_EDITOR)
if (ENABLE_EDITOR OR ENABLE_LAUNCHER)
# Widgets finds its own dependencies (QtGui and QtCore).
find_package(Qt5Widgets REQUIRED)
endif()
if (ENABLE_LAUNCHER)
find_package(Qt5Network REQUIRED)
endif()
if(ENABLE_TEST)
# find_package overwrites BOOST_* variables which are already set, so all components have to be
# included again
@ -133,6 +141,9 @@ endif()
if (ENABLE_EDITOR)
add_subdirectory(editor)
endif()
if (ENABLE_LAUNCHER)
add_subdirectory(launcher)
endif()
if(ENABLE_TEST)
add_subdirectory(test)
endif()

View File

@ -1,4 +1,25 @@
{
"name" : "In The Wake of Gods",
"description" : "Unnofficial addon for Heroes of Might and Magic III",
"version" : "3.58.0",
"author" : "WoG Team",
"artifacts" :
[
"config/wog/artifacts.json"
],
"creatures" :
[
"config/wog/creatures.json"
],
"factions" :
[
"config/wog/factions.json"
],
"filesystem":
{
"" :
@ -39,23 +60,5 @@
[
{"type" : "dir", "path" : "/Maps"}
]
},
"name" : "In The Wake of Gods",
"description" : "Unnofficial addon for Heroes of Might and Magic III",
"artifacts" :
[
"config/wog/artifacts.json"
],
"creatures" :
[
"config/wog/creatures.json"
],
"factions" :
[
"config/wog/factions.json"
]
}
}

View File

@ -1,4 +1,10 @@
{
"name" : "VCMI essential files",
"description" : "Essential files required for VCMI to run correctly",
"version" : "0.0",
"author" : "VCMI Team",
"filesystem":
{
"DATA/" :
@ -13,8 +19,5 @@
[
{"type" : "dir", "path" : "/Maps"}
]
},
"name" : "VCMI essential files",
"description" : "Essential files required for VCMI to run correctly"
}
}

View File

@ -3,7 +3,7 @@
"$schema": "http://json-schema.org/draft-04/schema",
"title" : "VCMI mod file format",
"description" : "Format used to define main mod file (mod.json) in VCMI",
"required" : [ "name", "description" ],
"required" : [ "name", "description", "version", "author" ],
"additionalProperties" : false,
"properties":{
@ -16,6 +16,26 @@
"description": "More lengthy description of mod. No hard limit"
},
"modType" : {
"type":"string",
"description": "Type of mod, e.g. Town, Artifacts, Graphical."
},
"version" : {
"type":"string",
"description": "Current mod version, up to 3 numbers, dot-separated. Format: A.B.C"
},
"author" : {
"type":"string",
"description": "Author of the mod. Can be nickname, real name or name of team"
},
"weblink" : {
"type":"string",
"description": "Home page of mod or link to forum thread"
},
"depends": {
"type":"array",
"description": "List of mods that are required to run this one",
@ -69,7 +89,7 @@
},
"type": {
"type" : "string",
"enum" : [ "dir", "lod", "snd", "vid", "map" ],
"enum" : [ "dir", "lod", "snd", "vid", "map", "zip" ],
"description" : "Type of data source"
}
}

View File

@ -3,7 +3,7 @@
{
"type" : "object",
"$schema": "http://json-schema.org/draft-04/schema",
"required" : [ "general", "video", "adventure", "battle", "server", "logging" ],
"required" : [ "general", "video", "adventure", "battle", "server", "logging", "launcher" ],
"definitions" : {
"logLevelEnum" : {
"type" : "string",
@ -224,6 +224,21 @@
}
}
}
},
"launcher" : {
"type" : "object",
"default": {},
"additionalProperties" : false,
"required" : [ "repositoryURL" ],
"properties" : {
"repositoryURL" : {
"type" : "array",
"default" : [ ],
"items" : {
"type" : "string"
}
}
}
}
}
}

View File

@ -2184,7 +2184,7 @@ SpellID CBattleInfoCallback::getRandomBeneficialSpell(const CStack * subject) co
break;
case SpellID::SLAYER://only if monsters are present
{
auto kingMonster = getStackIf([&](const CStack *stack) //look for enemy, non-shooting stack
auto kingMonster = getStackIf([&](const CStack *stack) -> bool //look for enemy, non-shooting stack
{
const auto isKing = Selector::type(Bonus::KING1)
.Or(Selector::type(Bonus::KING2))

View File

@ -294,18 +294,11 @@ void CHeroHandler::loadHeroSkills(CHero * hero, const JsonNode & node)
for(const JsonNode & spell : node["spellbook"].Vector())
{
if (spell.getType() == JsonNode::DATA_FLOAT) // for compatibility
VLC->modh->identifiers.requestIdentifier("spell", spell,
[=](si32 spellID)
{
hero->spells.insert(SpellID(spell.Float()));
}
else
{
VLC->modh->identifiers.requestIdentifier("spell", spell,
[=](si32 spellID)
{
hero->spells.insert(SpellID(spellID));
});
}
hero->spells.insert(SpellID(spellID));
});
}
}

View File

@ -156,10 +156,6 @@ bool CIdentifierStorage::resolveIdentifier(const ObjectCallback & request)
{
logGlobal->errorStream() << "\tID is available in mod " << it->second.scope;
}
// temporary code to smooth 0.92->0.93 transition
request.callback(entries.first->second.id);
return true;
}
logGlobal->errorStream() << "Unknown identifier " << request.type << "." << request.name << " from mod " << request.localScope;
return false;

View File

@ -339,7 +339,7 @@ void JsonWriter::writeEntry(JsonVector::const_iterator entry)
void JsonWriter::writeString(const std::string &string)
{
static const std::string escaped = "\"\\/\b\f\n\r\t";
static const std::string escaped = "\"\\\b\f\n\r\t";
out <<'\"';
size_t pos=0, start=0;
@ -506,7 +506,6 @@ bool JsonParser::extractEscaping(std::string &str)
{
break; case '\"': str += '\"';
break; case '\\': str += '\\';
break; case '/': str += '/';
break; case 'b': str += '\b';
break; case 'f': str += '\f';
break; case 'n': str += '\n';

View File

@ -302,7 +302,7 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs )
{
CGObjectInstance *obj = gs->getObjInstance(id);
logGlobal->debugStream() << "removing object id=" << id << "; address=" << (int)obj << "; name=" << obj->getHoverText();
logGlobal->debugStream() << "removing object id=" << id << "; address=" << (intptr_t)obj << "; name=" << obj->getHoverText();
//unblock tiles
if(obj->defInfo)
{
@ -595,7 +595,7 @@ DLL_LINKAGE void NewObject::applyGs( CGameState *gs )
o->initObj();
assert(o->defInfo);
logGlobal->debugStream() << "added object id=" << id << "; address=" << (int)o << "; name=" << o->getHoverText();
logGlobal->debugStream() << "added object id=" << id << "; address=" << (intptr_t)o << "; name=" << o->getHoverText();
}
DLL_LINKAGE void NewArtifact::applyGs( CGameState *gs )

View File

@ -14,6 +14,8 @@
struct z_stream_s;
/// Abstract class that provides buffer for one-directional input streams (e.g. compressed data)
/// Used for zip archives support and in .lod deflate compression
class CBufferedStream : public CInputStream
{
public:
@ -86,7 +88,7 @@ private:
/**
* A class which provides method definitions for reading a gzip-compressed file
* This class implements lazy loading - data will be decompressed (and cached by this class) only by request
* This class implements lazy loading - data will be decompressed (and cached) only by request
*/
class DLL_LINKAGE CCompressedStream : public CBufferedStream
{
@ -103,7 +105,7 @@ public:
~CCompressedStream();
/**
* Prepare stream for decompression of next block (e.g. nect part of h3c)
* Prepare stream for decompression of next block (e.g. next part of h3c)
* Applicable only for streams that contain multiple concatenated compressed data
*
* @return false if next block was not found, true othervice

View File

@ -2,6 +2,8 @@
#include "../../Global.h"
#include "CZipLoader.h"
#include "../ScopeGuard.h"
/*
* CZipLoader.cpp, part of VCMI engine
*
@ -100,3 +102,101 @@ std::unordered_set<ResourceID> CZipLoader::getFilteredFiles(std::function<bool(c
}
return foundID;
}
/// extracts currently selected file from zip into stream "where"
static bool extractCurrent(unzFile file, std::ostream & where)
{
std::array<char, 8 * 1024> buffer;
unzOpenCurrentFile(file);
while (1)
{
int readSize = unzReadCurrentFile(file, buffer.data(), buffer.size());
if (readSize < 0) // error
break;
if (readSize == 0) // end-of-file. Also performs CRC check
return unzCloseCurrentFile(file) == UNZ_OK;
if (readSize > 0) // successfull read
{
where.write(buffer.data(), readSize);
if (!where.good())
break;
}
}
// extraction failed. Close file and exit
unzCloseCurrentFile(file);
return false;
}
std::vector<std::string> ZipArchive::listFiles(std::string filename)
{
std::vector<std::string> ret;
unzFile file = unzOpen(filename.c_str());
if (unzGoToFirstFile(file) == UNZ_OK)
{
do
{
unz_file_info info;
std::vector<char> filename;
unzGetCurrentFileInfo (file, &info, nullptr, 0, nullptr, 0, nullptr, 0);
filename.resize(info.size_filename);
// Get name of current file. Contrary to docs "info" parameter can't be null
unzGetCurrentFileInfo (file, &info, filename.data(), filename.size(), nullptr, 0, nullptr, 0);
ret.push_back(std::string(filename.data(), filename.size()));
}
while (unzGoToNextFile(file) == UNZ_OK);
}
unzClose(file);
return ret;
}
bool ZipArchive::extract(std::string from, std::string where)
{
// Note: may not be fast enough for large archives (should NOT happen with mods)
// because locating each file by name may be slow. Unlikely slower than decompression though
return extract(from, where, listFiles(from));
}
bool ZipArchive::extract(std::string from, std::string where, std::vector<std::string> what)
{
unzFile archive = unzOpen(from.c_str());
auto onExit = vstd::makeScopeGuard([&]()
{
unzClose(archive);
});
for (std::string & file : what)
{
if (unzLocateFile(archive, file.c_str(), 1) != UNZ_OK)
return false;
std::string fullName = where + '/' + file;
std::string fullPath = fullName.substr(0, fullName.find_last_of("/"));
boost::filesystem::create_directories(fullPath);
// directory. No file to extract
// TODO: better way to detect directory? Probably check return value of unzOpenCurrentFile?
if (boost::algorithm::ends_with(file, "/"))
continue;
std::ofstream destFile(fullName);
if (!destFile.good())
return false;
if (!extractCurrent(archive, destFile))
return false;
}
return true;
}

View File

@ -55,3 +55,16 @@ public:
std::string getMountPoint() const override;
std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override;
};
namespace ZipArchive
{
/// List all files present in archive
std::vector<std::string> DLL_LINKAGE listFiles(std::string filename);
/// extracts all files from archive "from" into destination directory "where". Directory must exist
bool DLL_LINKAGE extract(std::string from, std::string where);
///same as above, but extracts only files mentioned in "what" list
bool DLL_LINKAGE extract(std::string from, std::string where, std::vector<std::string> what);
}

View File

@ -22,6 +22,7 @@
#include "../lib/VCMI_Lib.h"
#include "../lib/mapping/CMap.h"
#include "../lib/VCMIDirs.h"
#include "../lib/ScopeGuard.h"
#include "../client/CSoundBase.h"
#include "CGameHandler.h"
#include "CVCMIServer.h"
@ -3536,7 +3537,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
StartAction start_action(ba);
sendAndApply(&start_action);
auto makeScopeGuard([&]{ sendAndApply(&end_action); }); //if we started than we have to finish
auto onExit = vstd::makeScopeGuard([&]{ sendAndApply(&end_action); }); //if we started than we have to finish
const CGHeroInstance * attackingHero = gs->curB->battleGetFightingHero(ba.side);
CHeroHandler::SBallisticsLevelInfo sbi = VLC->heroh->ballistics[attackingHero->getSecSkillLevel(SecondarySkill::BALLISTICS)];