Example #1
0
JsonNode JsonReader::ParseArray() {

   JsonNode object = JsonNode(JsonNode::Type::Array);
   bool end = false;

   /* Verify we're parsing an array */
   if (*m_data == '[') m_data++;

   while (!end) {

      /* Use the index value as the key name */
      object[object.ChildCount()] = this->ParseValue();

      while (*m_data != ',' && *m_data != ']' && !EndOfFile()) m_data++;

      switch (*m_data) {

         case ',':
            m_data++;
            break;

         case ']':
            end = true;
            m_data++;
            break;

         default:
            PrintError("Syntax Error : ',' , ']' were expected. ");
            end = true;
            break;
      };
   }

   return object;
}
Example #2
0
void CAnimation::initFromJson(const JsonNode & config)
{
	std::string basepath;
	basepath = config["basepath"].String();

	for(const JsonNode &group : config["sequences"].Vector())
	{
		size_t groupID = group["group"].Float();//TODO: string-to-value conversion("moving" -> MOVING)
		source[groupID].clear();

		for(const JsonNode &frame : group["frames"].Vector())
		{
			source[groupID].push_back(JsonNode());
			std::string filename =  frame.String();
			source[groupID].back()["file"].String() = basepath + filename;
		}
	}

	for(const JsonNode &node : config["images"].Vector())
	{
		size_t group = node["group"].Float();
		size_t frame = node["frame"].Float();

		if (source[group].size() <= frame)
			source[group].resize(frame+1);

		source[group][frame] = node;
		std::string filename =  node["file"].String();
		source[group][frame]["file"].String() = basepath + filename;
	}
}
Example #3
0
void CArtHandler::afterLoadFinalization()
{
	//All artifacts have their id, so we can properly update their bonuses' source ids.
	for(auto &art : artifacts)
	{
		for(auto &bonus : art->getExportedBonusList())
		{
			assert(art == artifacts[art->id]);
			assert(bonus->source == Bonus::ARTIFACT);
			bonus->sid = art->id;
		}
	}

	for (CArtifact * art : artifacts)
	{
		VLC->objtypeh->loadSubObject(art->Name(), JsonNode(), Obj::ARTIFACT, art->id.num);

		if (!art->advMapDef.empty())
		{
			JsonNode templ;
			templ["animation"].String() = art->advMapDef;

			// add new template.
			// Necessary for objects added via mods that don't have any templates in H3
			VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, art->id)->addTemplate(templ);
		}
		// object does not have any templates - this is not usable object (e.g. pseudo-art like lock)
		if (VLC->objtypeh->getHandlerFor(Obj::ARTIFACT, art->id)->getTemplates().empty())
			VLC->objtypeh->removeSubObject(Obj::ARTIFACT, art->id);
	}
}
Example #4
0
JsonNode JsonReader::ParseObject() {

   JsonNode object = JsonNode(JsonNode::Type::Object);
   bool end = false;

   if (*m_data == '{') m_data++;

   /* Look for the next key name */
   while (!end) {

      std::string key;

      /* Look for string quotes */
      while (*m_data != '\"' && *m_data != '\'' && !EndOfFile()) m_data++;

      if (EndOfFile()) {
         PrintError("Syntax Error : '\"' , ''' were expected. ");
         break;
      }

      /* Parse the key as string */
      key = ParseString();

      SkipUntil(':');

      if (EndOfFile()) {
         PrintError("Syntax Error : ':' was expected. ");
         break;
      }

      m_data++;

      object[key] = this->ParseValue();

      while (*m_data != ',' && *m_data != '}' && !EndOfFile()) m_data++;

      switch (*m_data) {

         case ',':

            m_data++;
            break;

         case '}':

            end = true;
            m_data++;
            break;

         default:

            PrintError("Syntax Error : ',' , '}' were expected. ");
            end = true;
            break;
      };
   }

   return object;
}
Example #5
0
void CModHandler::loadGameContent()
{
	CStopWatch timer, totalTime;

	CContentHandler content;
	logGlobal->infoStream() << "\tInitializing content handler: " << timer.getDiff() << " ms";

	// first - load virtual "core" mod that contains all data
	// TODO? move all data into real mods? RoE, AB, SoD, WoG
	content.preloadModData("core", JsonNode(ResourceID("config/gameConfig.json")));
	logGlobal->infoStream() << "\tParsing original game data: " << timer.getDiff() << " ms";

	for(const TModID & modName : activeMods)
	{
		logGlobal->infoStream() << "\t\t" << allMods[modName].name;

		std::string modFileName = "mods/" + modName + "/mod.json";

		const JsonNode config = JsonNode(ResourceID(modFileName));
		JsonUtils::validate(config, "vcmi:mod", modName);

		content.preloadModData(modName, config);
	}
	logGlobal->infoStream() << "\tParsing mod data: " << timer.getDiff() << " ms";

	content.loadMod("core");
	logGlobal->infoStream() << "\tLoading original game data: " << timer.getDiff() << " ms";

	for(const TModID & modName : activeMods)
	{
		content.loadMod(modName);
		logGlobal->infoStream() << "\t\t" << allMods[modName].name;
	}
	logGlobal->infoStream() << "\tLoading mod data: " << timer.getDiff() << "ms";

	VLC->creh->loadCrExpBon();
	VLC->creh->buildBonusTreeForTiers(); //do that after all new creatures are loaded
	identifiers.finalize();
	logGlobal->infoStream() << "\tResolving identifiers: " << timer.getDiff() << " ms";

	content.afterLoadFinalization();
	logGlobal->infoStream() << "\tHandlers post-load finalization: " << timer.getDiff() << " ms";

	logGlobal->infoStream() << "\tAll game content loaded in " << totalTime.getDiff() << " ms";
}
Example #6
0
void CModHandler::loadMods()
{
	const JsonNode modConfig = loadModSettings("config/modSettings.json");

	loadMods("", "", modConfig["activeMods"], true);

	coreMod = CModInfo("core", modConfig["core"], JsonNode(ResourceID("config/gameConfig.json")));
	coreMod.name = "Original game files";
}
Example #7
0
JsonNode JsonReader::Parse(const char *filename) {

   std::ifstream file(filename, std::ios::in | std::ios::binary);

   if (!file.is_open()) {
      std::cout << "Fatal Error: File \"" << filename << "\" doesn't exist."
                << std::endl;
      return JsonNode();
   } else {
      return this->Parse(file);
   }

}
Example #8
0
std::vector<JsonNode> CArtHandler::loadLegacyData(size_t dataSize)
{
	artifacts.resize(dataSize);
	std::vector<JsonNode> h3Data;
	h3Data.reserve(dataSize);

	#define ART_POS(x) #x ,
	const std::vector<std::string> artSlots = { ART_POS_LIST };
	#undef ART_POS

	static std::map<char, std::string> classes =
		{{'S',"SPECIAL"}, {'T',"TREASURE"},{'N',"MINOR"},{'J',"MAJOR"},{'R',"RELIC"},};

	CLegacyConfigParser parser("DATA/ARTRAITS.TXT");
	CLegacyConfigParser events("DATA/ARTEVENT.TXT");

	parser.endLine(); // header
	parser.endLine();

	for (size_t i = 0; i < dataSize; i++)
	{
		JsonNode artData;

		artData["text"]["name"].String() = parser.readString();
		artData["text"]["event"].String() = events.readString();
		artData["value"].Float() = parser.readNumber();

		for(auto & artSlot : artSlots)
		{
			if(parser.readString() == "x")
			{
				artData["slot"].Vector().push_back(JsonNode());
				artData["slot"].Vector().back().String() = artSlot;
			}
		}
		artData["class"].String() = classes[parser.readString()[0]];
		artData["text"]["description"].String() = parser.readString();

		parser.endLine();
		events.endLine();
		h3Data.push_back(artData);
	}
	return h3Data;
}
Example #9
0
void CModHandler::loadMods(std::string path, std::string parent, const JsonNode & modSettings, bool enableMods)
{
	for (std::string modName : getModList(path))
	{
		boost::to_lower(modName);
		std::string modFullName = parent.empty() ? modName : parent + '.' + modName;

		if (CResourceHandler::get("initial")->existsResource(ResourceID(CModInfo::getModFile(modFullName))))
		{
			CModInfo mod(modFullName, modSettings[modName], JsonNode(ResourceID(CModInfo::getModFile(modFullName))));
			if (!parent.empty()) // this is submod, add parent to dependecies
				mod.dependencies.insert(parent);

			allMods[modFullName] = mod;
			if (mod.enabled && enableMods)
				activeMods.push_back(modFullName);

			loadMods(CModInfo::getModDir(modFullName) + '/', modFullName, modSettings[modName]["mods"], enableMods && mod.enabled);
		}
	}
}
Example #10
0
void CModHandler::initialize(std::vector<std::string> availableMods)
{
	std::string confName = "config/modSettings.json";
	JsonNode modConfig;

	// Porbably new install. Create initial configuration
	if (!CResourceHandler::get()->existsResource(ResourceID(confName)))
		CResourceHandler::get()->createResource(confName);
	else
		modConfig = JsonNode(ResourceID(confName));

	const JsonNode & modList = modConfig["activeMods"];
	JsonNode resultingList;

	std::vector <TModID> detectedMods;

	for(std::string name : availableMods)
	{
		boost::to_lower(name);
		std::string modFileName = "mods/" + name + "/mod.json";

		if (CResourceHandler::get()->existsResource(ResourceID(modFileName)))
		{
			const JsonNode config = JsonNode(ResourceID(modFileName));

			if (config.isNull())
				continue;

			if (!modList[name].isNull() && modList[name].Bool() == false )
			{
				resultingList[name].Bool() = false;
				continue; // disabled mod
			}
			resultingList[name].Bool() = true;

			CModInfo & mod = allMods[name];

			mod.identifier = name;
			mod.name = config["name"].String();
			mod.description =  config["description"].String();
			mod.dependencies = config["depends"].convertTo<std::set<std::string> >();
			mod.conflicts =    config["conflicts"].convertTo<std::set<std::string> >();
			detectedMods.push_back(name);
		}
		else
            logGlobal->warnStream() << "\t\t Directory " << name << " does not contains VCMI mod";
	}

	if (!checkDependencies(detectedMods))
	{
        logGlobal->errorStream() << "Critical error: failed to load mods! Exiting...";
		exit(1);
	}

	activeMods = resolveDependencies(detectedMods);

	modConfig["activeMods"] = resultingList;
	CResourceHandler::get()->createResource("CONFIG/modSettings.json");

	std::ofstream file(CResourceHandler::get()->getResourceName(ResourceID("config/modSettings.json")), std::ofstream::trunc);
	file << modConfig;
}
Example #11
0
void SimpleJsonParser::parse( std::vector<CString>& tokens )
{
    enum ParseState {
        SCAN=1,
        ARRAY,
        PAIR,
        PAIR_COLON,
        RVALUE,
        RVALUE_SEPARATOR
    };

    ParseState state = SCAN;
    LPCSTR tag_name = NULL;
    CString array_index;
    std::stack<JsonNode *> nodeStack;

    m_values.clear();
    m_type = JSONROOT;

    nodeStack.push( this );

    for ( CString& token : tokens ) {
        // printf( "%s ", (LPCSTR)token );

        switch ( state ) {
            case SCAN:
                if ( token == "[" ) {                   // Start of array
                    m_type = JSONARRAY;
                    state = RVALUE;
                    break;
                }
                else if ( token == "{" ) {              // Start of object
                    m_type = JSONOBJECT;
                    state = PAIR;
                    break;
                }

                throw std::exception( "Parser expected opening object or array" );

            case PAIR:
                // Check for empty object
                if ( token == "}" && nodeStack.top()->m_type == JSONOBJECT && nodeStack.top()->m_values.size() == 0 ) {
                    nodeStack.pop();
                    state = RVALUE_SEPARATOR;
                    break;
                }

                tag_name = strip_quotes( token );
                state = PAIR_COLON;
                break;

            case PAIR_COLON:
                if ( token != ":" )
                    throw std::exception( "Parser expecting colon seperator" );
                state = RVALUE;
                break;

            case RVALUE: {
                if ( token == "]" ) {       // Empty array
                    if ( nodeStack.top()->m_type != JSONARRAY  )
                        throw std::exception( "Unexpected array closing bracket" );

                    nodeStack.pop();
                    state = RVALUE_SEPARATOR;
                    break;
                }

                JsonNode* node = nodeStack.top();

                if ( node->m_type == JSONARRAY ) {
                    array_index.Format( "%d", node->m_values.size() );
                    tag_name = (LPCSTR)array_index;
                }

                if ( node->m_values.find( tag_name ) != node->m_values.end() ) {
                    CString error;
                    error.Format( "Duplicate JSON tag name '%s'", tag_name );
                    throw std::exception( (LPCSTR)error );
                }

                if ( token == "[" ) {
                    node->m_values[ tag_name ] = JsonNode( JSONARRAY );
                    state = RVALUE;
                    nodeStack.push( &node->m_values[ tag_name ] );
                    break;
                }

                if ( token == "{" ) {
                    node->m_values[ tag_name ] = JsonNode( JSONOBJECT );
                    state = PAIR;
                    nodeStack.push( &node->m_values[ tag_name ] );
                    break;
                }

                // Add a constant to current node container

                if ( node->m_type != JSONOBJECT && node->m_type != JSONARRAY)
                    throw std::exception( "Parser expecting container JSON node" );

                node->m_values[ tag_name ] = JsonNode( strip_quotes( token ) );
                state = RVALUE_SEPARATOR;
                break;
            }

            case RVALUE_SEPARATOR: {
                JsonNode* node = nodeStack.top();

                if ( token == "," ) {
                    state = node->m_type == JSONARRAY ? RVALUE : PAIR;
                    break;
                }

                if ( token == "}" && node->m_type == JSONOBJECT  ) {
                    nodeStack.pop();
                    break;
                }

                if ( token == "]" && node->m_type == JSONARRAY ) {
                    // Assert all non-null nodes in the array are the same type
                    JsonNodeType expected_type = JSONNULL;
                    for ( auto child : node->m_values ) {
                        if ( child.second.m_type == JSONNULL )
                            ;
                        else if ( expected_type == JSONNULL )
                            expected_type = child.second.m_type;
                        else if ( child.second.m_type != expected_type ) {
                            CString error;
                            error.Format( "Mixed object types in '%s'", child.first );
                            throw std::exception( (LPCSTR)error );
                        }
                    }

                    nodeStack.pop();
                    break;
                }

                throw std::exception( "Parser expecting object or array seperator" );
            }
        }
    }

    if ( nodeStack.size() > 0 )
        throw std::exception( "Unclosed JSON objects detected" );
}