浏览代码

Added validation of game settings

Should detect invalid config in all sources of settings - vcmi config,
mods, random map templates
Ivan Savenko 1 年之前
父节点
当前提交
e07340b531
共有 4 个文件被更改,包括 155 次插入9 次删除
  1. 151 0
      config/schemas/gameSettings.json
  2. 1 6
      config/schemas/mod.json
  3. 1 3
      config/schemas/template.json
  4. 2 0
      lib/GameSettings.cpp

+ 151 - 0
config/schemas/gameSettings.json

@@ -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" }
+			}
+		},
+	}
+}

+ 1 - 6
config/schemas/mod.json

@@ -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",

+ 1 - 3
config/schemas/template.json

@@ -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",

+ 2 - 0
lib/GameSettings.cpp

@@ -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];