Ejemplo n.º 1
0
        public static void LogWarning(System.Object obj, string message)
        {
            // Set the hasWarnings flag
            IContractConfiguratorFactory ccFactory = obj as IContractConfiguratorFactory;

            if (ccFactory != null)
            {
                ccFactory.hasWarnings = true;
            }

            LoggingUtil.Log(LogLevel.WARNING, obj.GetType(), message);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Checks if all the given ContractRequirement meet the requirement.
        /// </summary>
        /// <param name="contract">Contract to check</param>
        /// <param name="contractType">Contract type of the contract (in case the contract type has not yet been assigned).</param>
        /// <param name="contractRequirements">The list of requirements to check</param>
        /// <returns>Whether the requirement is met or not.</returns>
        public static bool RequirementsMet(ConfiguredContract contract, ContractType contractType, IEnumerable <ContractRequirement> contractRequirements)
        {
            bool allReqMet = true;

            try
            {
                LoggingUtil.LogVerbose(typeof(ContractRequirement), "Checking requirements for contract '{0}'", contractType.name);
                foreach (ContractRequirement requirement in contractRequirements)
                {
                    if (requirement.enabled)
                    {
                        if (requirement.checkOnActiveContract || contract == null || contract.ContractState != Contract.State.Active)
                        {
                            allReqMet = allReqMet && requirement.CheckRequirement(contract);

                            if (!allReqMet)
                            {
                                LoggingUtil.Log(contract != null && contract.ContractState == Contract.State.Active ? LoggingUtil.LogLevel.INFO :
                                                contract != null && contract.ContractState == Contract.State.Offered ? LoggingUtil.LogLevel.DEBUG : LoggingUtil.LogLevel.VERBOSE,
                                                requirement.GetType(), "Contract {0}: requirement {1} was not met.", contractType.name, requirement.name);
                                break;
                            }
                        }
                    }
                }

                // Force fail the contract if a requirement becomes unmet
                if (contract != null && contract.ContractState == Contract.State.Active && !allReqMet)
                {
                    // Fail the contract - unfortunately, the player won't know why. :(
                    contract.Fail();

                    // Force the stock contracts window to refresh
                    GameEvents.Contract.onContractsLoaded.Fire();
                }
            }
            catch (Exception e)
            {
                LoggingUtil.LogException(new Exception("ContractConfigurator: Exception checking requirements!", e));
                return(false);
            }
            return(allReqMet);
        }
Ejemplo n.º 3
0
        public static void LogWarning(System.Object obj, string message)
        {
            // Set the hasWarnings flag
            IContractConfiguratorFactory ccFactory = obj as IContractConfiguratorFactory;

            if (ccFactory == null && captureLog && ConfigNodeUtil.currentDataNode != null)
            {
                ccFactory = ConfigNodeUtil.currentDataNode.Factory;
            }
            else
            {
                DataNode dataNode = obj as DataNode;
                if (dataNode != null)
                {
                    ccFactory = dataNode.Factory;
                }
            }
            if (ccFactory != null)
            {
                ccFactory.hasWarnings = true;
            }

            LoggingUtil.Log(LogLevel.WARNING, obj.GetType(), message);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Generates a ContractRequirement from a configuration node.
        /// </summary>
        /// <param name="configNode">ConfigNode to use in the generation.</param>
        /// <param name="contractType">ContractType that this requirement falls under</param>
        /// <param name="requirement">The ContractRequirement object.</param>
        /// <returns>Whether the load was successful</returns>
        public static bool GenerateRequirement(ConfigNode configNode, ContractType contractType, out ContractRequirement requirement,
                                               IContractConfiguratorFactory parent = null)
        {
            // Logging on
            LoggingUtil.CaptureLog = true;
            bool valid = true;

            // Get the type
            string type = configNode.GetValue("type");
            string name = configNode.HasValue("name") ? configNode.GetValue("name") : type;

            if (string.IsNullOrEmpty(type))
            {
                LoggingUtil.LogError(typeof(ParameterFactory), "CONTRACT_TYPE '{0}', REQUIREMENT '{1}' does not specify the mandatory 'type' attribute.",
                                     contractType.name, configNode.GetValue("name"));
                requirement = new InvalidContractRequirement();
                valid       = false;
            }
            else if (!requirementTypes.ContainsKey(type))
            {
                LoggingUtil.LogError(typeof(ParameterFactory), "CONTRACT_TYPE '{0}', REQUIREMENT '{1}' of type '{2}': Unknown requirement '{3}'.",
                                     contractType.name, configNode.GetValue("name"), configNode.GetValue("type"), type);
                requirement = new InvalidContractRequirement();
                valid       = false;
            }
            else
            {
                // Create an instance of the ContractRequirement
                requirement = (ContractRequirement)Activator.CreateInstance(requirementTypes[type]);
            }

            // Set attributes
            requirement.contractType = contractType;
            requirement.dataNode     = new DataNode(name, parent != null ? parent.dataNode : contractType.dataNode, requirement);

            // Load config
            valid &= requirement.LoadFromConfig(configNode);

            // Override the needsTitle if we have a parent node with hideChildren
            ContractRequirement parentRequirement = parent as ContractRequirement;

            if (parentRequirement != null)
            {
                if (parentRequirement.hideChildren)
                {
                    requirement.hideChildren = true;
                    requirement.needsTitle   = false;
                }
            }

            // Check for unexpected values - always do this last
            if (requirement.GetType() != typeof(InvalidContractRequirement))
            {
                valid &= ConfigNodeUtil.ValidateUnexpectedValues(configNode, requirement);
            }

            // Load child nodes
            foreach (ConfigNode childNode in ConfigNodeUtil.GetChildNodes(configNode, "REQUIREMENT"))
            {
                ContractRequirement child = null;
                valid &= ContractRequirement.GenerateRequirement(childNode, contractType, out child, requirement);
                if (child != null)
                {
                    requirement.childNodes.Add(child);
                    if (child.hasWarnings)
                    {
                        requirement.hasWarnings = true;
                    }
                }
            }

            // Error for missing title
            if (requirement.needsTitle && string.IsNullOrEmpty(requirement.title))
            {
                valid = contractType.minVersion < ContractConfigurator.ENHANCED_UI_VERSION;
                LoggingUtil.Log(contractType.minVersion >= ContractConfigurator.ENHANCED_UI_VERSION ? LoggingUtil.LogLevel.ERROR : LoggingUtil.LogLevel.WARNING,
                                requirement, "{0}: missing required attribute 'title'.", requirement.ErrorPrefix(configNode));
            }

            requirement.enabled    = valid;
            requirement.log        = LoggingUtil.capturedLog;
            LoggingUtil.CaptureLog = false;

            return(valid);
        }
Ejemplo n.º 5
0
 public static void LogInfo(System.Object obj, string message)
 {
     LoggingUtil.Log(LogLevel.INFO, obj.GetType(), message);
 }
Ejemplo n.º 6
0
 public static void LogInfo(Type type, string message)
 {
     LoggingUtil.Log(LogLevel.INFO, type, message);
 }
Ejemplo n.º 7
0
 public static void LogDebug(System.Object obj, string message)
 {
     LoggingUtil.Log(LogLevel.DEBUG, obj.GetType(), message);
 }
Ejemplo n.º 8
0
 public static void LogDebug(Type type, string message)
 {
     LoggingUtil.Log(LogLevel.DEBUG, type, message);
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Checks if the "basic" requirements that shouldn't change due to expressions are met.
        /// </summary>
        /// <param name="contract">The contract</param>
        /// <returns>Whether the contract can be offered.</returns>
        public bool MeetBasicRequirements(ConfiguredContract contract)
        {
            LoggingUtil.LogLevel origLogLevel = LoggingUtil.logLevel;
            try
            {
                // Turn tracing on
                if (trace)
                {
                    LoggingUtil.logLevel = LoggingUtil.LogLevel.VERBOSE;
                    LoggingUtil.LogWarning(this, "Tracing enabled for contract type " + name);
                }

                // Check funding
                if (advanceFunds < 0)
                {
                    CurrencyModifierQuery q = new CurrencyModifierQuery(TransactionReasons.ContractAdvance, -advanceFunds, 0.0f, 0.0f);
                    GameEvents.Modifiers.OnCurrencyModifierQuery.Fire(q);
                    float fundsRequired = advanceFunds + q.GetEffectDelta(Currency.Funds);

                    if (!Funding.CanAfford(fundsRequired))
                    {
                        throw new ContractRequirementException("Can't afford contract advance cost.");
                    }
                }

                // Check expiry
                if ((contract.ContractState == Contract.State.Offered || contract.ContractState == Contract.State.Withdrawn) &&
                    Planetarium.fetch != null && contract.DateExpire < Planetarium.fetch.time)
                {
                    throw new ContractRequirementException("Expired contract.");
                }

                // Checks for maxSimultaneous/maxCompletions
                if (maxSimultaneous != 0 || maxCompletions != 0)
                {
                    IEnumerable <ConfiguredContract> contractList = ConfiguredContract.CurrentContracts.
                                                                    Where(c => c.contractType != null && c.contractType.name == name && c != contract);

                    // Check if we're breaching the active limit
                    int activeContracts = contractList.Count();
                    if (maxSimultaneous != 0 && activeContracts >= maxSimultaneous)
                    {
                        throw new ContractRequirementException("Too many active contracts.");
                    }

                    // Check if we're breaching the completed limit
                    if (maxCompletions != 0)
                    {
                        if (ActualCompletions() + activeContracts >= maxCompletions)
                        {
                            throw new ContractRequirementException("Too many completed/active/offered contracts.");
                        }
                    }
                }

                // Check the group values
                if (group != null)
                {
                    CheckContractGroup(contract, group);
                }

                return(true);
            }
            catch (ContractRequirementException e)
            {
                LoggingUtil.LogLevel level = contract.ContractState == Contract.State.Active ? LoggingUtil.LogLevel.INFO : contract.contractType != null ? LoggingUtil.LogLevel.DEBUG : LoggingUtil.LogLevel.VERBOSE;
                string prefix = contract.contractType != null ? "Cancelling contract of type " + name + " (" + contract.Title + "): " :
                                "Didn't generate contract of type " + name + ": ";
                LoggingUtil.Log(level, this.GetType(), prefix + e.Message);
                return(false);
            }
            catch
            {
                LoggingUtil.LogError(this, "Exception while attempting to check requirements of contract type " + name);
                throw;
            }
            finally
            {
                LoggingUtil.logLevel = origLogLevel;
                loaded = true;
            }
        }
Ejemplo n.º 10
0
 public static void LogVerbose(Type type, string message, params Object[] parameters)
 {
     LoggingUtil.Log(LogLevel.VERBOSE, type, message, parameters);
 }
Ejemplo n.º 11
0
 public static void LogWarning(Type type, string message)
 {
     LoggingUtil.Log(LogLevel.WARNING, type, message);
 }
Ejemplo n.º 12
0
 public static void LogError(Type type, string message)
 {
     LoggingUtil.Log(LogLevel.ERROR, type, message);
 }
Ejemplo n.º 13
0
 public static void LogDebug(Type type, string message, params object[] parameters)
 {
     LoggingUtil.Log(LogLevel.DEBUG, type, message, parameters);
 }
Ejemplo n.º 14
0
 public static void LogError(Type type, string message, params object[] parameters)
 {
     LoggingUtil.Log(LogLevel.ERROR, type, message, parameters);
 }
Ejemplo n.º 15
0
 public static void LogWarning(Type type, string message, params object[] parameters)
 {
     LoggingUtil.Log(LogLevel.WARNING, type, message, parameters);
 }
Ejemplo n.º 16
0
 public static void LogInfo(Type type, string message, params Object[] parameters)
 {
     LoggingUtil.Log(LogLevel.INFO, type, message, parameters);
 }
Ejemplo n.º 17
0
 public static void LogInfo(System.Object obj, string message, params object[] parameters)
 {
     LoggingUtil.Log(LogLevel.INFO, obj.GetType(), message, parameters);
 }
Ejemplo n.º 18
0
 public static void LogError(System.Object obj, string message)
 {
     LoggingUtil.Log(LogLevel.ERROR, obj.GetType(), message);
 }
Ejemplo n.º 19
0
 public static void LogVerbose(System.Object obj, string message)
 {
     LoggingUtil.Log(LogLevel.VERBOSE, obj.GetType(), message);
 }
Ejemplo n.º 20
0
        /// <summary>
        /// Loads the contract type details from the given config node.
        /// </summary>
        /// <param name="configNode">The config node to load from.</param>
        /// <returns>Whether the load was successful.</returns>
        public bool Load(ConfigNode configNode)
        {
            LoggingUtil.LogLevel origLogLevel = LoggingUtil.logLevel;

            try
            {
                // Logging on
                LoggingUtil.CaptureLog = true;
                ConfigNodeUtil.SetCurrentDataNode(null);
                LoggingUtil.LogInfo(this, "Loading CONTRACT_TYPE: '" + name + "'");

                // Clear the config node cache
                ConfigNodeUtil.ClearCache(true);

                // Load values that are immediately required
                bool valid = true;
                valid &= ConfigNodeUtil.ParseValue <ContractGroup>(configNode, "group", x => group = x, this, (ContractGroup)null);

                // Set up the data node
                dataNode = new DataNode(configNode.GetValue("name"), group != null ? group.dataNode : null, this);
                ConfigNodeUtil.SetCurrentDataNode(dataNode);

                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "name", x => name = x, this);

                // Try to turn on trace mode
                valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "trace", x => trace = x, this, false);
                if (trace)
                {
                    LoggingUtil.logLevel = LoggingUtil.LogLevel.VERBOSE;
                    LoggingUtil.LogWarning(this, "Tracing enabled for contract type " + name);
                }

                // Load contract text details
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "title", x => title = x, this);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "tag", x => tag = x, this, "");
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "description", x => description = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "topic", x => topic = x, this, "");
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "subject", x => subject = x, this, "");
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "notes", x => notes = x, this, (string)null);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "synopsis", x => synopsis = x, this);
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "completedMessage", x => completedMessage = x, this);

                if (configNode.HasValue("motivation)"))
                {
                    string motivation;
                    valid &= ConfigNodeUtil.ParseValue <string>(configNode, "motivation", x => motivation = x, this, "");
                    LoggingUtil.LogWarning(this, "The 'motivation' attribute is no longer supported as of Contract Configurator 1.23.0");
                }

                // Load optional attributes
                valid &= ConfigNodeUtil.ParseValue <Agent>(configNode, "agent", x => agent = x, this, group != null ? group.agent : null);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "minExpiry", x => minExpiry = x, this, 5.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "maxExpiry", x => maxExpiry = x, this, 100.0f, x => Validation.GE(x, minExpiry));
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "deadline", x => deadline = x, this, 0.0f, x => Validation.GE(x, 0.0f));
                valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "cancellable", x => cancellable = x, this, true);
                valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "declinable", x => declinable = x, this, true);
                valid &= ConfigNodeUtil.ParseValue <bool>(configNode, "autoAccept", x => autoAccept = x, this, false);
                valid &= ConfigNodeUtil.ParseValue <List <Contract.ContractPrestige> >(configNode, "prestige", x => prestige = x, this, new List <Contract.ContractPrestige>());
                valid &= ConfigNodeUtil.ParseValue <CelestialBody>(configNode, "targetBody", x => targetBody = x, this, (CelestialBody)null);

                valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxCompletions", x => maxCompletions = x, this, 0, x => Validation.GE(x, 0));
                valid &= ConfigNodeUtil.ParseValue <int>(configNode, "maxSimultaneous", x => maxSimultaneous = x, this, (maxCompletions == 0 ? 4 : 0), x => Validation.GE(x, 0));

                // Load rewards
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "rewardFunds", x => rewardFunds = x, this, 0.0f);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "rewardReputation", x => rewardReputation = x, this, 0.0f);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "rewardScience", x => rewardScience = x, this, 0.0f);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "failureFunds", x => failureFunds = x, this, 0.0f);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "failureReputation", x => failureReputation = x, this, 0.0f);
                valid &= ConfigNodeUtil.ParseValue <float>(configNode, "advanceFunds", x => advanceFunds = x, this, 0.0f);

                // Load other values
                if (configNode.HasValue("weight"))
                {
                    double weight;
                    valid &= ConfigNodeUtil.ParseValue <double>(configNode, "weight", x => weight = x, this);
                    LoggingUtil.LogWarning(this, ErrorPrefix() + ": The weight attribute is deprecated as of Contract Configurator 1.15.0.  Contracts are no longer generated using a weighted system.");
                }

                // Merge in data from the parent contract group
                for (ContractGroup currentGroup = group; currentGroup != null; currentGroup = currentGroup.parent)
                {
                    // Merge dataValues - this is a flag saying what values need to be unique at the contract level
                    foreach (KeyValuePair <string, DataValueInfo> pair in currentGroup.dataValues)
                    {
                        dataValues[currentGroup.name + ":" + pair.Key] = pair.Value;
                    }

                    // Merge uniquenessChecks
                    foreach (KeyValuePair <string, DataNode.UniquenessCheck> pair in currentGroup.uniquenessChecks)
                    {
                        uniquenessChecks[currentGroup.name + ":" + pair.Key] = pair.Value;
                    }
                }

                // Load DATA nodes
                valid &= dataNode.ParseDataNodes(configNode, this, dataValues, uniquenessChecks);

                log = LoggingUtil.capturedLog;
                LoggingUtil.CaptureLog = false;

                // Load parameters
                foreach (ConfigNode contractParameter in ConfigNodeUtil.GetChildNodes(configNode, "PARAMETER"))
                {
                    ParameterFactory paramFactory = null;
                    valid &= ParameterFactory.GenerateParameterFactory(contractParameter, this, out paramFactory);
                    if (paramFactory != null)
                    {
                        paramFactories.Add(paramFactory);
                        if (paramFactory.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Load behaviours
                foreach (ConfigNode requirementNode in ConfigNodeUtil.GetChildNodes(configNode, "BEHAVIOUR"))
                {
                    BehaviourFactory behaviourFactory = null;
                    valid &= BehaviourFactory.GenerateBehaviourFactory(requirementNode, this, out behaviourFactory);
                    if (behaviourFactory != null)
                    {
                        behaviourFactories.Add(behaviourFactory);
                        if (behaviourFactory.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Load requirements
                foreach (ConfigNode requirementNode in ConfigNodeUtil.GetChildNodes(configNode, "REQUIREMENT"))
                {
                    ContractRequirement requirement = null;
                    valid &= ContractRequirement.GenerateRequirement(requirementNode, this, out requirement);
                    if (requirement != null)
                    {
                        requirements.Add(requirement);
                        if (requirement.hasWarnings)
                        {
                            hasWarnings = true;
                        }
                    }
                }

                // Logging on
                LoggingUtil.CaptureLog = true;

                // Check we have at least one valid parameter
                if (paramFactories.Count() == 0)
                {
                    LoggingUtil.LogError(this, ErrorPrefix() + ": Need at least one parameter for a contract!");
                    valid = false;
                }

                ConfigNodeUtil.SetCurrentDataNode(dataNode);

                //
                // Process the DATA_EXPAND nodes - this could cause a restart to the load process
                //
                ConfigNode dataExpandNode = configNode.GetNodes("DATA_EXPAND").FirstOrDefault();
                if (dataExpandNode != null)
                {
                    Type type = null;
                    valid &= ConfigNodeUtil.ParseValue <Type>(dataExpandNode, "type", x => type = x, this);

                    if (type != null)
                    {
                        foreach (ConfigNode.Value pair in dataExpandNode.values)
                        {
                            string key = pair.name;
                            if (key != "type")
                            {
                                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 ParseDataExpandString method generic value
                                MethodInfo method = methodParseExpand.MakeGenericMethod(new Type[] { type });

                                // Invoke the ParseDataExpandString method
                                List <string> values = (List <string>)method.Invoke(this, new object[] { dataExpandNode, key });

                                // Stop at this point if we're invalid
                                if (values == null || !valid)
                                {
                                    if (values == null)
                                    {
                                        LoggingUtil.LogWarning(this, ErrorPrefix() + ": Received an empty list of values when trying to do a DATA_EXPAND");
                                    }
                                    valid = false;
                                    break;
                                }

                                // Expand
                                configNode.RemoveNode(dataExpandNode);
                                foreach (string val in values)
                                {
                                    // Set up for expansion
                                    ConfigNode copy    = configNode.CreateCopy();
                                    string     newName = name + "." + val;
                                    copy.SetValue("name", newName);

                                    // Set up the data node in the copy
                                    ConfigNode dataNode = new ConfigNode("DATA");
                                    copy.AddNode(dataNode);
                                    dataNode.AddValue("type", dataExpandNode.GetValue("type"));
                                    dataNode.AddValue(key, val);

                                    ContractType contractTypeCopy = new ContractType(newName);
                                    contractTypeCopy.Load(copy);
                                }

                                // Remove the original
                                contractTypes.Remove(name);

                                // Don't do any more loading for this one
                                LoggingUtil.LogInfo(this, "Successfully expanded CONTRACT_TYPE '" + name + "'");
                                return(valid);
                            }
                        }
                    }
                }

                //
                // Do the deferred loads
                //
                valid &= ConfigNodeUtil.ExecuteDeferredLoads();

                //
                // Do generic fields that need to happen after deferred loads
                //
                ConfigNodeUtil.SetCurrentDataNode(dataNode);

                // Generic title
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "genericTitle", x => genericTitle = x, this, title);
                if (!configNode.HasValue("genericTitle") && !dataNode.IsDeterministic("title"))
                {
                    LoggingUtil.Log(minVersion >= ContractConfigurator.ENHANCED_UI_VERSION ? LoggingUtil.LogLevel.ERROR : LoggingUtil.LogLevel.WARNING, this,
                                    ErrorPrefix() + ": The field 'genericTitle' is required when the title is not determistic (ie. when expressions are used).");

                    // Error on newer versions of contract packs
                    if (minVersion >= ContractConfigurator.ENHANCED_UI_VERSION)
                    {
                        valid = false;
                    }
                }
                else if (!dataNode.IsDeterministic("genericTitle"))
                {
                    valid = false;
                    LoggingUtil.LogError(this, ErrorPrefix() + ": The field 'genericTitle' must be deterministic.");
                }

                // Generic description
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "genericDescription", x => genericDescription = x, this, description);
                if (!configNode.HasValue("genericDescription") && !dataNode.IsDeterministic("description"))
                {
                    LoggingUtil.Log(minVersion >= ContractConfigurator.ENHANCED_UI_VERSION ? LoggingUtil.LogLevel.ERROR : LoggingUtil.LogLevel.WARNING, this,
                                    ErrorPrefix() + ": The field 'genericDescription' is required when the description is not determistic (ie. when expressions are used).");

                    // Error on newer versions of contract packs
                    if (minVersion >= ContractConfigurator.ENHANCED_UI_VERSION)
                    {
                        valid = false;
                    }
                }
                else if (!dataNode.IsDeterministic("genericDescription"))
                {
                    valid = false;
                    LoggingUtil.LogError(this, ErrorPrefix() + ": The field 'genericDescription' must be deterministic.");
                }

                // Sorting key
                valid &= ConfigNodeUtil.ParseValue <string>(configNode, "sortKey", x => sortKey = x, this, genericTitle);

                // Check for unexpected values - always do this last
                valid &= ConfigNodeUtil.ValidateUnexpectedValues(configNode, this);

                if (valid)
                {
                    LoggingUtil.LogInfo(this, "Successfully loaded CONTRACT_TYPE '" + name + "'");
                }
                else
                {
                    LoggingUtil.LogWarning(this, "Errors encountered while trying to load CONTRACT_TYPE '" + name + "'");
                }
                config  = configNode.ToString();
                hash    = config.GetHashCode();
                enabled = valid;
                log    += LoggingUtil.capturedLog;

                if (LoggingUtil.logLevel >= LoggingUtil.LogLevel.DEBUG)
                {
                    // Get the contract configurator log file
                    string[] dirComponents  = new string[] { KSPUtil.ApplicationRootPath, "GameData", "ContractConfigurator", "log", (group == null ? "!NO_GROUP" : group.Root.name) };
                    string[] pathComponents = dirComponents.Union(new string[] { name + ".log" }).ToArray();
                    string   dir            = string.Join(Path.DirectorySeparatorChar.ToString(), dirComponents);
                    string   path           = string.Join(Path.DirectorySeparatorChar.ToString(), pathComponents);

                    // Delete the file if it exists
                    if (File.Exists(path))
                    {
                        try
                        {
                            File.Delete(path);
                        }
                        catch (Exception e)
                        {
                            LoggingUtil.LogException(new Exception("Exception while attempting to delete the file: " + path, e));
                        }
                    }

                    // Create the directory if it doesn't exist
                    Directory.CreateDirectory(dir);

                    // Now write the config and the cleaned up log to it
                    try
                    {
                        using (StreamWriter sw = File.AppendText(path))
                        {
                            sw.Write("Debug information for CONTRACT_TYPE '" + name + "':\n");
                            sw.Write("\nConfiguration:\n");
                            sw.Write(config);
                            sw.Write("\nData Nodes:\n");
                            sw.Write(DataNodeDebug(dataNode));
                            sw.Write("\nOutput log:\n");
                            sw.Write(log);
                        }
                    }
                    catch
                    {
                        LoggingUtil.LogError(this, "Exception while attempting to write to the file: " + path);
                    }
                }

                return(valid);
            }
            catch (Exception e)
            {
                enabled = false;
                throw new Exception("Error loading CONTRACT_TYPE '" + name + "'", e);
            }
            finally
            {
                LoggingUtil.CaptureLog = false;
                LoggingUtil.logLevel   = origLogLevel;
                loaded = true;
            }
        }
Ejemplo n.º 21
0
 public static void LogVerbose(Type type, string message)
 {
     LoggingUtil.Log(LogLevel.VERBOSE, type, message);
 }
Ejemplo n.º 22
0
        /// <summary>
        /// Checks if the "extended" requirements that change due to expressions.
        /// </summary>
        /// <param name="contract">The contract</param>
        /// <returns>Whether the contract can be offered.</returns>
        public bool MeetExtendedRequirements(ConfiguredContract contract, ContractType contractType)
        {
            LoggingUtil.LogLevel origLogLevel = LoggingUtil.logLevel;
            try
            {
                // Turn tracing on
                if (trace)
                {
                    LoggingUtil.logLevel = LoggingUtil.LogLevel.VERBOSE;
                    LoggingUtil.LogWarning(this, "Tracing enabled for contract type " + name);
                }

                // Hash check
                if (contract.ContractState == Contract.State.Offered && contract.hash != hash)
                {
                    throw new ContractRequirementException("Contract definition changed.");
                }

                // Check prestige
                if (prestige.Count > 0 && !prestige.Contains(contract.Prestige))
                {
                    throw new ContractRequirementException("Wrong prestige level.");
                }

                // Do a Research Bodies check, if applicable
                ResearchBodiesCheck(contract);

                // Check special values are not null
                if (contract.contractType == null)
                {
                    foreach (KeyValuePair <string, DataValueInfo> pair in dataValues)
                    {
                        // Only check if it is a required value
                        if (pair.Value.required)
                        {
                            CheckRequiredValue(pair.Key);
                        }
                    }
                }

                if (contract.contractType == null || contract.ContractState == Contract.State.Generated || contract.ContractState == Contract.State.Withdrawn)
                {
                    // Check for unique values against other contracts of the same type
                    foreach (KeyValuePair <string, DataNode.UniquenessCheck> pair in uniquenessChecks.Where(p => contract.uniqueData.ContainsKey(p.Key)))
                    {
                        string key = pair.Key;
                        DataNode.UniquenessCheck uniquenessCheck = pair.Value;

                        LoggingUtil.LogVerbose(this, "Doing unique value check for " + key);

                        // Get the active/offered contract lists
                        IEnumerable <ConfiguredContract> contractList = ConfiguredContract.CurrentContracts.
                                                                        Where(c => c != null && c.contractType != null && c != contract);

                        // Add in finished contracts
                        if (uniquenessCheck == DataNode.UniquenessCheck.CONTRACT_ALL || uniquenessCheck == DataNode.UniquenessCheck.GROUP_ALL)
                        {
                            contractList = contractList.Union(ContractSystem.Instance.ContractsFinished.OfType <ConfiguredContract>().
                                                              Where(c => c != null && c.contractType != null && c != contract));
                        }

                        // Filter anything that doesn't have our key
                        contractList = contractList.Where(c => c.uniqueData.ContainsKey(key));

                        // Check for contracts of the same type
                        if (uniquenessCheck == DataNode.UniquenessCheck.CONTRACT_ALL || uniquenessCheck == DataNode.UniquenessCheck.CONTRACT_ACTIVE)
                        {
                            contractList = contractList.Where(c => c.contractType.name == name);
                        }
                        // Check for a shared group
                        else if (contractType.group != null)
                        {
                            contractList = contractList.Where(c => c.contractType.group != null && c.contractType.group.name == contractType.group.name);
                        }
                        // Shared lack of group
                        else
                        {
                            contractList = contractList.Where(c => c.contractType.group == null);
                        }

                        object val = contract.uniqueData[key];
                        if (val != null)
                        {
                            // Special case for vessels - convert to the Guid
                            Vessel vessel = val as Vessel;
                            if (vessel != null)
                            {
                                val = vessel.id;
                            }

                            foreach (ConfiguredContract otherContract in contractList)
                            {
                                if (val.Equals(otherContract.uniqueData[key]))
                                {
                                    throw new ContractRequirementException("Failed on unique value check for key '" + key + "'.");
                                }
                            }
                        }
                    }
                }

                // Check the captured requirements
                if (!ContractRequirement.RequirementsMet(contract, this, contract.requirements != null ? contract.requirements : requirements))
                {
                    throw new ContractRequirementException("Failed on contract requirement check.");
                }

                return(true);
            }
            catch (ContractRequirementException e)
            {
                LoggingUtil.LogLevel level = contract.ContractState == Contract.State.Active ? LoggingUtil.LogLevel.INFO : contract.contractType != null ? LoggingUtil.LogLevel.DEBUG : LoggingUtil.LogLevel.VERBOSE;
                string prefix = contract.contractType != null ? "Cancelling contract of type " + name + " (" + contract.Title + "): " :
                                "Didn't generate contract of type " + name + ": ";
                LoggingUtil.Log(level, this.GetType(), prefix + e.Message);
                return(false);
            }
            catch
            {
                LoggingUtil.LogError(this, "Exception while attempting to check requirements of contract type " + name);
                throw;
            }
            finally
            {
                LoggingUtil.logLevel = origLogLevel;
                loaded = true;
            }
        }
 public static void LogWarning(System.Object obj, string message)
 {
     LoggingUtil.Log(LogLevel.WARNING, obj.GetType(), message);
 }