mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Added validation of game settings
Should detect invalid config in all sources of settings - vcmi config, mods, random map templates
This commit is contained in:
		
							
								
								
									
										151
									
								
								config/schemas/gameSettings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								config/schemas/gameSettings.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | ||||
| { | ||||
| 	"type" : "object", | ||||
| 	"$schema" : "http://json-schema.org/draft-04/schema", | ||||
| 	"title" : "VCMI game settings format", | ||||
| 	"description" : "Format used to define game settings in VCMI", | ||||
| 	"additionalProperties" : false, | ||||
| 	"properties" : { | ||||
| 		"textData" : { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"heroClass"   : { "type" : "number" }, | ||||
| 				"artifact"    : { "type" : "number" }, | ||||
| 				"creature"    : { "type" : "number" }, | ||||
| 				"faction"     : { "type" : "number" }, | ||||
| 				"hero"        : { "type" : "number" }, | ||||
| 				"spell"       : { "type" : "number" }, | ||||
| 				"object"      : { "type" : "number" }, | ||||
| 				"terrain"     : { "type" : "number" }, | ||||
| 				"river"       : { "type" : "number" }, | ||||
| 				"road"        : { "type" : "number" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"mapFormat" : { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"restorationOfErathia" : { "type" : "object" }, | ||||
| 				"armageddonsBlade" :     { "type" : "object" }, | ||||
| 				"shadowOfDeath" :        { "type" : "object" }, | ||||
| 				"chronicles" :           { "type" : "object" }, | ||||
| 				"jsonVCMI" :             { "type" : "object" }, | ||||
| 				"hornOfTheAbyss" :       { "type" : "object" }, | ||||
| 				"inTheWakeOfGods" :      { "type" : "object" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"heroes" : { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"perPlayerOnMapCap"  :        { "type" : "number" }, | ||||
| 				"perPlayerTotalCap"  :        { "type" : "number" }, | ||||
| 				"retreatOnWinWithoutTroops" : { "type" : "boolean" }, | ||||
| 				"startingStackChances" :      { "type" : "array" }, | ||||
| 				"backpackSize" :              { "type" : "number" }, | ||||
| 				"tavernInvite" :              { "type" : "boolean" }, | ||||
| 				"minimalPrimarySkills" :      { "type" : "array" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"towns" : { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"buildingsPerTurnCap"  :    { "type" : "number" }, | ||||
| 				"startingDwellingChances" : { "type" : "array" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"combat": { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"goodMoraleDice" :              { "type" : "array" }, | ||||
| 				"badMoraleDice" :               { "type" : "array" }, | ||||
| 				"goodLuckDice" :                { "type" : "array" }, | ||||
| 				"badLuckDice" :                 { "type" : "array" }, | ||||
| 				"backpackSize" :                { "type" : "number" }, | ||||
| 				"attackPointDamageFactor" :     { "type" : "number" }, | ||||
| 				"attackPointDamageFactorCap" :  { "type" : "number" }, | ||||
| 				"defensePointDamageFactor" :    { "type" : "number" }, | ||||
| 				"defensePointDamageFactorCap" : { "type" : "number" }, | ||||
| 				"oneHexTriggersObstacles" :     { "type" : "boolean" }, | ||||
| 				"layouts" :                     { "type" : "object" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"creatures": { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"weeklyGrowthPercent" :     { "type" : "number" }, | ||||
| 				"weeklyGrowthCap" :         { "type" : "number" }, | ||||
| 				"dailyStackExperience" :    { "type" : "number" }, | ||||
| 				"allowRandomSpecialWeeks" : { "type" : "boolean" }, | ||||
| 				"allowAllForDoubleMonth" :  { "type" : "boolean" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"dwellings": { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"accumulateWhenNeutral" :  { "type" : "boolean" }, | ||||
| 				"accumulateWhenOwned" :  { "type" : "boolean" }, | ||||
| 				"mergeOnRecruit" :  { "type" : "boolean" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"markets": { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"blackMarketRestockPeriod" : { "type" : "number" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"banks": { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"showGuardsComposition" : { "type" : "boolean" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"modules": { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"stackExperience" : { "type" : "boolean" }, | ||||
| 				"stackArtifact" : { "type" : "boolean" }, | ||||
| 				"commanders" : { "type" : "boolean" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"pathfinder": { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"ignoreGuards" :            { "type" : "boolean" }, | ||||
| 				"useBoat" :                 { "type" : "boolean" }, | ||||
| 				"useMonolithTwoWay" :       { "type" : "boolean" }, | ||||
| 				"useMonolithOneWayUnique" : { "type" : "boolean" }, | ||||
| 				"useMonolithOneWayRandom" : { "type" : "boolean" }, | ||||
| 				"useWhirlpool" :            { "type" : "boolean" }, | ||||
| 				"originalFlyRules" :        { "type" : "boolean" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"spells": { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"dimensionDoorOnlyToUncoveredTiles" : { "type" : "boolean" }, | ||||
| 				"dimensionDoorExposesTerrainType" :   { "type" : "boolean" }, | ||||
| 				"dimensionDoorFailureSpendsPoints" :  { "type" : "boolean" }, | ||||
| 				"dimensionDoorTriggersGuards" :       { "type" : "boolean" }, | ||||
| 				"dimensionDoorTournamentRulesLimit" : { "type" : "boolean" } | ||||
| 			} | ||||
| 		}, | ||||
| 		"bonuses": { | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : false, | ||||
| 			"properties" : { | ||||
| 				"global" : { "type" : "object" }, | ||||
| 				"perHero" : { "type" : "object" } | ||||
| 			} | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
| @@ -124,12 +124,7 @@ | ||||
| 		"settings" : { | ||||
| 			"type" : "object", | ||||
| 			"description" : "List of changed game settings by mod", | ||||
| 			"additionalProperties" : { | ||||
| 				"type" : "object", | ||||
| 				"properties" : {  | ||||
| 					"type" : "object" | ||||
| 				} | ||||
| 			} | ||||
| 			"$ref" : "gameSettings.json" | ||||
| 		}, | ||||
| 		"filesystem" : { | ||||
| 			"type" : "object", | ||||
|   | ||||
| @@ -134,9 +134,7 @@ | ||||
| 		"settings" : { | ||||
| 			"description" : "List of changed game settings by template", | ||||
| 			"type" : "object", | ||||
| 			"additionalProperties" : { | ||||
| 				"type" : "object" | ||||
| 			} | ||||
| 			"$ref" : "gameSettings.json" | ||||
| 		}, | ||||
| 		"name" : { | ||||
| 			"description" : "Optional name - useful to have several template variations with same name", | ||||
|   | ||||
| @@ -104,6 +104,8 @@ const std::vector<GameSettings::SettingOption> GameSettings::settingProperties = | ||||
|  | ||||
| void GameSettings::loadBase(const JsonNode & input) | ||||
| { | ||||
| 	JsonUtils::validate(input, "vcmi:gameSettings", input.getModScope()); | ||||
|  | ||||
| 	for(const auto & option : settingProperties) | ||||
| 	{ | ||||
| 		const JsonNode & optionValue = input[option.group][option.key]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user