/// <summary> /// Parses the child DATA nodes out of the given config node, and returns the parsed values back in dataValues. /// </summary> /// <param name="configNode">The ConfigNode to load child DATA nodes from.</param> /// <param name="obj">The ContractConfigurator object to load from.</param> /// <param name="dataValues"></param> /// <param name="uniquenessChecks"></param> /// <returns></returns> public bool ParseDataNodes(ConfigNode configNode, IContractConfiguratorFactory obj, Dictionary <string, ContractType.DataValueInfo> dataValues, Dictionary <string, UniquenessCheck> uniquenessChecks) { bool valid = true; foreach (ConfigNode data in ConfigNodeUtil.GetChildNodes(configNode, "DATA")) { Type type = null; bool requiredValue = true; bool hidden = true; bool isLiteral = false; string title = ""; ConfigNodeUtil.SetCurrentDataNode(null); valid &= ConfigNodeUtil.ParseValue <Type>(data, "type", x => type = x, obj); valid &= ConfigNodeUtil.ParseValue <bool>(data, "requiredValue", x => requiredValue = x, obj, true); valid &= ConfigNodeUtil.ParseValue <string>(data, "title", x => title = x, obj, ""); valid &= ConfigNodeUtil.ParseValue <bool>(data, "hidden", x => hidden = x, obj, false); valid &= ConfigNodeUtil.ParseValue <bool>(data, "isLiteral", x => isLiteral = x, obj, false); bool doneTitleWarning = false; UniquenessCheck uniquenessCheck = UniquenessCheck.NONE; // Backwards compatibility for Contract Configurator 1.8.3 if (data.HasValue("uniqueValue") || data.HasValue("activeUniqueValue")) { LoggingUtil.LogWarning(this, "The use of uniqueValue and activeUniqueValue is obsolete since Contract Configurator 1.9.0, use uniquenessCheck instead."); bool uniqueValue = false; bool activeUniqueValue = false; valid &= ConfigNodeUtil.ParseValue <bool>(data, "uniqueValue", x => uniqueValue = x, obj, false); valid &= ConfigNodeUtil.ParseValue <bool>(data, "activeUniqueValue", x => activeUniqueValue = x, obj, false); uniquenessCheck = activeUniqueValue ? UniquenessCheck.CONTRACT_ACTIVE : uniqueValue ? UniquenessCheck.CONTRACT_ALL : UniquenessCheck.NONE; } else { valid &= ConfigNodeUtil.ParseValue <UniquenessCheck>(data, "uniquenessCheck", x => uniquenessCheck = x, obj, UniquenessCheck.NONE); } ConfigNodeUtil.SetCurrentDataNode(this); if (type != null) { foreach (ConfigNode.Value pair in data.values) { string name = pair.name; if (name != "type" && name != "title" && name != "hidden" && name != "requiredValue" && name != "uniqueValue" && name != "activeUniqueValue" && name != "uniquenessCheck" && name != "isLiteral") { if (uniquenessCheck != UniquenessCheck.NONE) { uniquenessChecks[name] = uniquenessCheck; } object value = null; // Create the setter function Type actionType = typeof(Action <>).MakeGenericType(type); Delegate del = Delegate.CreateDelegate(actionType, value, typeof(DataNode).GetMethod("NullAction")); // Set the ParseValue method generic MethodInfo method = (isLiteral ? methodParseValueLiteral : methodParseValue).MakeGenericMethod(new Type[] { type }); // Invoke the ParseValue method if (isLiteral) { this[name] = method.Invoke(null, new object[] { data, name, false }); } else { valid &= (bool)method.Invoke(null, new object[] { data, name, del, obj }); } dataValues[name] = new ContractType.DataValueInfo(title, requiredValue, hidden, type); // Recommend a title if (!data.HasValue("title") && requiredValue && !IsDeterministic(name) && !hidden && !doneTitleWarning && !dataValues[name].IsIgnoredType()) { doneTitleWarning = true; LoggingUtil.Log(obj.minVersion >= ContractConfigurator.ENHANCED_UI_VERSION ? LoggingUtil.LogLevel.ERROR : LoggingUtil.LogLevel.WARNING, this, obj.ErrorPrefix() + ": " + name + ": The field 'title' is required in for data node values where 'requiredValue' is true. Alternatively, the attribute 'hidden' can be set to true (but be careful - this can cause player confusion if all lines for the contract type show as 'Met' and the contract isn't generating)."); // Error on newer versions of contract packs if (obj.minVersion >= ContractConfigurator.ENHANCED_UI_VERSION) { valid = false; } } } } } } return(valid); }
/// <summary> /// Parses the child DATA nodes out of the given config node, and returns the parsed values back in dataValues. /// </summary> /// <param name="configNode">The ConfigNode to load child DATA nodes from.</param> /// <param name="obj">The ContractConfigurator object to load from.</param> /// <param name="dataValues"></param> /// <param name="uniquenessChecks"></param> /// <returns></returns> public bool ParseDataNodes(ConfigNode configNode, IContractConfiguratorFactory obj, Dictionary<string, ContractType.DataValueInfo> dataValues, Dictionary<string, UniquenessCheck> uniquenessChecks) { bool valid = true; foreach (ConfigNode data in ConfigNodeUtil.GetChildNodes(configNode, "DATA")) { Type type = null; bool requiredValue = true; bool hidden = true; string title = ""; ConfigNodeUtil.SetCurrentDataNode(null); valid &= ConfigNodeUtil.ParseValue<Type>(data, "type", x => type = x, obj); valid &= ConfigNodeUtil.ParseValue<bool>(data, "requiredValue", x => requiredValue = x, obj, true); valid &= ConfigNodeUtil.ParseValue<string>(data, "title", x => title = x, obj, ""); valid &= ConfigNodeUtil.ParseValue<bool>(data, "hidden", x => hidden = x, obj, false); bool doneTitleWarning = false; UniquenessCheck uniquenessCheck = UniquenessCheck.NONE; // Backwards compatibility for Contract Configurator 1.8.3 if (data.HasValue("uniqueValue") || data.HasValue("activeUniqueValue")) { LoggingUtil.LogWarning(this, "The use of uniqueValue and activeUniqueValue is obsolete since Contract Configurator 1.9.0, use uniquenessCheck instead."); bool uniqueValue = false; bool activeUniqueValue = false; valid &= ConfigNodeUtil.ParseValue<bool>(data, "uniqueValue", x => uniqueValue = x, obj, false); valid &= ConfigNodeUtil.ParseValue<bool>(data, "activeUniqueValue", x => activeUniqueValue = x, obj, false); uniquenessCheck = activeUniqueValue ? UniquenessCheck.CONTRACT_ACTIVE : uniqueValue ? UniquenessCheck.CONTRACT_ALL : UniquenessCheck.NONE; } else { valid &= ConfigNodeUtil.ParseValue<UniquenessCheck>(data, "uniquenessCheck", x => uniquenessCheck = x, obj, UniquenessCheck.NONE); } ConfigNodeUtil.SetCurrentDataNode(this); if (type != null) { foreach (ConfigNode.Value pair in data.values) { string name = pair.name; if (name != "type" && name != "title" && name != "hidden" && name != "requiredValue" && name != "uniqueValue" && name != "activeUniqueValue" && name != "uniquenessCheck") { if (uniquenessCheck != UniquenessCheck.NONE) { uniquenessChecks[name] = uniquenessCheck; } object value = null; // Create the setter function Type actionType = typeof(Action<>).MakeGenericType(type); Delegate del = Delegate.CreateDelegate(actionType, value, typeof(DataNode).GetMethod("NullAction")); // Set the ParseValue method generic MethodInfo method = methodParseValue.MakeGenericMethod(new Type[] { type }); // Invoke the ParseValue method valid &= (bool)method.Invoke(null, new object[] { data, name, del, obj }); dataValues[name] = new ContractType.DataValueInfo(title, requiredValue, hidden, type); // Recommend a title if (!data.HasValue("title") && requiredValue && !IsDeterministic(name) && !hidden && !doneTitleWarning && !dataValues[name].IsIgnoredType()) { doneTitleWarning = true; LoggingUtil.Log(obj.minVersion >= ContractConfigurator.ENHANCED_UI_VERSION ? LoggingUtil.LogLevel.ERROR : LoggingUtil.LogLevel.WARNING, this, obj.ErrorPrefix() + ": " + name + ": The field 'title' is required in for data node values where 'requiredValue' is true. Alternatively, the attribute 'hidden' can be set to true (but be careful - this can cause player confusion if all lines for the contract type show as 'Met' and the contract isn't generating)."); // Error on newer versions of contract packs if (obj.minVersion >= ContractConfigurator.ENHANCED_UI_VERSION) { valid = false; } } } } } } return valid; }