/// <summary>
        /// Loads all the contact type nodes and creates ContractType objects.
        /// </summary>
        private IEnumerator <YieldInstruction> LoadContractTypeConfig()
        {
            LoggingUtil.LogDebug(this, "Loading CONTRACT_TYPE nodes.");
            ConfigNode[] contractConfigs = GameDatabase.Instance.GetConfigNodes("CONTRACT_TYPE");
            totalContracts = contractConfigs.Count();

            // First pass - create all the ContractType objects
            foreach (ConfigNode contractConfig in contractConfigs)
            {
                // Create the initial contract type
                LoggingUtil.LogVerbose(this, "Pre-load for node: '{0}'", contractConfig.GetValue("name"));
                try
                {
                    ContractType contractType = new ContractType(contractConfig.GetValue("name"));
                }
                catch (ArgumentException)
                {
                    LoggingUtil.LogError(this, "Couldn't load CONTRACT_TYPE '{0}' due to a duplicate name.", contractConfig.GetValue("name"));
                }
            }

            // Second pass - do the actual loading of details
            foreach (ConfigNode contractConfig in contractConfigs)
            {
                attemptedContracts++;
                if (reloading)
                {
                    yield return(new WaitForEndOfFrame());
                }

                // Fetch the contractType
                string       name         = contractConfig.GetValue("name");
                ContractType contractType = ContractType.GetContractType(name);
                if (contractType != null && !contractType.loaded)
                {
                    // Perform the load
                    try
                    {
                        contractType.Load(contractConfig);
                        if (contractType.enabled)
                        {
                            successContracts++;
                        }
                    }
                    catch (Exception e)
                    {
                        LoggingUtil.LogException(e);
                    }
                }
            }

            LoggingUtil.LogInfo(this, "Loaded {0} out of {1} CONTRACT_TYPE nodes.", successContracts, totalContracts);

            // Check for empty groups and warn
            foreach (ContractGroup group in ContractGroup.contractGroups.Values.Where(g => g != null))
            {
                group.CheckEmpty();
            }

            // Load other things
            MissionControlUI.GroupContainer.LoadConfig();

            if (!reloading && LoggingUtil.logLevel == LoggingUtil.LogLevel.DEBUG || LoggingUtil.logLevel == LoggingUtil.LogLevel.VERBOSE)
            {
                ScreenMessages.PostScreenMessage("Contract Configurator: Loaded " + successContracts + " out of " + totalContracts
                                                 + " contracts successfully.", 5, ScreenMessageStyle.UPPER_CENTER);
            }
        }
        /// <summary>
        /// Attempts to parse a value from the config node.  Returns a default value if not found.
        /// Validates return values using the given function.
        /// </summary>
        /// <typeparam name="T">The type of value to convert to.</typeparam>
        /// <param name="configNode">The ConfigNode to read from.</param>
        /// <param name="key">The key to examine.</param>
        /// <param name="setter">Function used to set the output value</param>
        /// <param name="obj">Factory object for error messages.</param>
        /// <param name="defaultValue">Default value to use if there is no key in the config node</param>
        /// <param name="validation">Validation function to run against the returned value</param>
        /// <returns>The parsed value (or default value if not found)</returns>
        public static bool ParseValue <T>(ConfigNode configNode, string key, Action <T> setter, IContractConfiguratorFactory obj, T defaultValue, Func <T, bool> validation)
        {
            // Initialize the data type of the expression
            if (currentDataNode != null && !currentDataNode.IsInitialized(key))
            {
                currentDataNode.BlankInit(key, typeof(T));
            }

            bool valid = true;
            T    value = defaultValue;

            if (configNode.HasValue(key) || configNode.HasNode(key))
            {
                try
                {
                    // Check whether there's a value
                    if (configNode.HasValue(key) && string.IsNullOrEmpty(configNode.GetValue(key)))
                    {
                        LoggingUtil.LogError(obj, "{0}: Required value '{1}' is empty.", obj.ErrorPrefix(configNode), key);
                        valid = false;
                    }
                    else
                    {
                        // Load value
                        value = ParseValue <T>(configNode, key, true);
                    }

                    // If value was non-null, run validation
                    if (value != null && (typeof(T) != typeof(string) || ((string)(object)value) != ""))
                    {
                        try
                        {
                            valid = validation.Invoke(value);
                            if (!valid)
                            {
                                // In general, the validation function should throw an exception and give a much better message
                                LoggingUtil.LogError(obj, "{0}: A validation error occured while loading the key '{1}' with value '{2}'.", obj.ErrorPrefix(configNode), key, value);
                            }
                        }
                        catch (Exception e)
                        {
                            if (e is DataNode.ValueNotInitialized)
                            {
                                throw;
                            }

                            LoggingUtil.LogError(obj, "{0}: A validation error occured while loading the key '{1}' with value '{2}'.", obj.ErrorPrefix(configNode), key, value);
                            LoggingUtil.LogException(e);
                            valid = false;
                        }
                    }
                }
                catch (Exception e)
                {
                    if (e.GetType() == typeof(DataNode.ValueNotInitialized))
                    {
                        string dependency = ((DataNode.ValueNotInitialized)e).key;
                        string path       = currentDataNode.Path() + key;

                        LoggingUtil.LogVerbose(typeof(ConfigNodeUtil), "Trying to load {0}, but {1} is uninitialized.", path, dependency);

                        // Defer loading this value
                        DeferredLoadObject <T> loadObj = null;
                        if (!deferredLoads.ContainsKey(path) || deferredLoads[path].GetType().GetGenericArguments().First() != typeof(T))
                        {
                            deferredLoads[path] = new DeferredLoadObject <T>(configNode, key, setter, obj, validation, currentDataNode);
                        }
                        loadObj = (DeferredLoadObject <T>)deferredLoads[path];

                        // New dependency - try again
                        if (!loadObj.dependencies.Contains(dependency))
                        {
                            LoggingUtil.LogVerbose(typeof(ConfigNodeUtil), "    New dependency, will re-attempt to load later.");
                            loadObj.dependencies.Add(dependency);
                            return(true);
                        }
                    }

                    LoggingUtil.LogError(obj, "{0}: Error parsing {1}", obj.ErrorPrefix(configNode), key);

                    // Return immediately on deferred load error
                    if (e.GetType() == typeof(DataNode.ValueNotInitialized))
                    {
                        DataNode.ValueNotInitialized vni = e as DataNode.ValueNotInitialized;
                        LoggingUtil.LogException(new Exception(StringBuilderCache.Format("Unknown identifier '@{0}'.", vni.key)));
                        return(false);
                    }
                    LoggingUtil.LogException(e);

                    valid = false;
                }
                finally
                {
                    AddFoundKey(configNode, key);
                }
            }

            // Store the value
            if (currentDataNode != null)
            {
                currentDataNode[key] = value;

                if (!currentDataNode.IsDeterministic(key) && initialLoad)
                {
                    currentDataNode.DeferredLoads.Add(new DeferredLoadObject <T>(configNode, key, setter, obj, validation, currentDataNode));
                }
            }

            // Invoke the setter function
            if (valid)
            {
                setter.Invoke(value);
            }

            return(valid);
        }
Пример #3
0
        /// <summary>
        /// Tests whether a contract can be offered.
        /// </summary>
        /// <param name="contract">The contract</param>
        /// <returns>Whether the contract can be offered.</returns>
        public bool MeetRequirements(ConfiguredContract contract)
        {
            // Hash check
            if (contract.ContractState == Contract.State.Offered && contract.hash != hash)
            {
                LoggingUtil.LogDebug(this, "Cancelling offered contract of type " + name + ", contract definition changed.");
                return(false);
            }

            // Check prestige
            if (prestige.Count > 0 && !prestige.Contains(contract.Prestige))
            {
                LoggingUtil.LogVerbose(this, "Didn't generate contract type " + name + ", wrong prestige level.");
                return(false);
            }

            // Checks for maxSimultaneous/maxCompletions
            if (maxSimultaneous != 0 || maxCompletions != 0)
            {
                // Get the count of active contracts - excluding ours
                int activeContracts = ContractSystem.Instance.GetCurrentContracts <ConfiguredContract>().
                                      Count(c => c.contractType != null && c.contractType.name == name);
                if (contract.ContractState == Contract.State.Offered || contract.ContractState == Contract.State.Active)
                {
                    activeContracts--;
                }

                // Check if we're breaching the active limit
                if (maxSimultaneous != 0 && activeContracts >= maxSimultaneous)
                {
                    LoggingUtil.LogVerbose(this, "Didn't generate contract type " + name + ", too many active contracts.");
                    return(false);
                }

                // Check if we're breaching the completed limit
                if (maxCompletions != 0)
                {
                    int finishedContracts = ContractSystem.Instance.GetCompletedContracts <ConfiguredContract>().
                                            Count(c => c.contractType != null && c.contractType.name == name);
                    if (finishedContracts + activeContracts >= maxCompletions)
                    {
                        LoggingUtil.LogVerbose(this, "Didn't generate contract type " + name + ", too many completed/active/offered contracts.");
                        return(false);
                    }
                }
            }

            // Check the group values
            if (group != null)
            {
                // Check the group active limit
                int activeContracts = ContractSystem.Instance.GetCurrentContracts <ConfiguredContract>().Count(c => c.contractType != null && c.contractType.group == group);
                if (contract.ContractState == Contract.State.Offered || contract.ContractState == Contract.State.Active)
                {
                    activeContracts--;
                }

                if (group.maxSimultaneous != 0 && activeContracts >= group.maxSimultaneous)
                {
                    LoggingUtil.LogVerbose(this, "Didn't generate contract type " + name + ", too many active contracts in group.");
                    return(false);
                }

                // Check the group completed limit
                if (group.maxCompletions != 0)
                {
                    int finishedContracts = ContractSystem.Instance.GetCompletedContracts <ConfiguredContract>().Count(c => c.contractType != null && c.contractType.group == group);
                    if (finishedContracts + activeContracts >= maxCompletions)
                    {
                        LoggingUtil.LogVerbose(this, "Didn't generate contract type " + name + ", too many completed contracts in group.");
                        return(false);
                    }
                }
            }

            // Check special values are not null
            if (contract.ContractState != Contract.State.Active)
            {
                foreach (KeyValuePair <string, bool> pair in dataValues)
                {
                    // Only check if it is a required value
                    if (pair.Value)
                    {
                        string name = pair.Key;

                        object o = dataNode[name];
                        if (o == null)
                        {
                            LoggingUtil.LogVerbose(this, "Didn't generate contract type " + this.name + ", '" + name + "' was null.");
                            return(false);
                        }
                        else if (o == typeof(List <>))
                        {
                            PropertyInfo prop  = o.GetType().GetProperty("Count");
                            int          count = (int)prop.GetValue(o, null);
                            if (count == 0)
                            {
                                LoggingUtil.LogVerbose(this, "Didn't generate contract type " + this.name + ", '" + name + "' had zero count.");
                                return(false);
                            }
                        }
                        else if (o == typeof(Vessel))
                        {
                            Vessel v = (Vessel)o;

                            if (v.state == Vessel.State.DEAD)
                            {
                                LoggingUtil.LogVerbose(this, "Didn't generate contract type " + this.name + ", vessel '" + v.vesselName + "' is dead.");
                                return(false);
                            }
                        }
                    }
                }
            }

            // Check the captured requirements
            return(ContractRequirement.RequirementsMet(contract, this, requirements));
        }
Пример #4
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;
            }
        }
        /// <summary>
        /// Loads all the contact configuration nodes and creates ContractType objects.
        /// </summary>
        private IEnumerator <YieldInstruction> LoadContractConfig()
        {
            // Load all the contract groups
            LoggingUtil.LogDebug(this, "Loading CONTRACT_GROUP nodes.");
            ConfigNode[] contractGroups = GameDatabase.Instance.GetConfigNodes("CONTRACT_GROUP");

            foreach (ConfigNode groupConfig in contractGroups)
            {
                // Create the group
                string name = groupConfig.GetValue("name");
                LoggingUtil.LogInfo(this, "Loading CONTRACT_GROUP: '" + name + "'");
                ContractGroup contractGroup = null;
                try
                {
                    contractGroup = new ContractGroup(name);
                }
                catch (ArgumentException)
                {
                    LoggingUtil.LogError(this, "Couldn't load CONTRACT_GROUP '" + name + "' due to a duplicate name.");
                }

                // Peform the actual load
                if (contractGroup != null)
                {
                    bool success = false;
                    try
                    {
                        ConfigNodeUtil.ClearCache(true);
                        success = contractGroup.Load(groupConfig);
                    }
                    catch (Exception e)
                    {
                        Exception wrapper = new Exception("Error loading CONTRACT_GROUP '" + name + "'", e);
                        LoggingUtil.LogException(wrapper);
                    }
                    finally
                    {
                        if (!success)
                        {
                            ContractGroup.contractGroups.Remove(name);
                        }
                    }
                }
            }

            LoggingUtil.LogDebug(this, "Loading CONTRACT_TYPE nodes.");
            ConfigNode[] contractConfigs = GameDatabase.Instance.GetConfigNodes("CONTRACT_TYPE");
            totalContracts = contractConfigs.Count();

            // First pass - create all the ContractType objects
            foreach (ConfigNode contractConfig in contractConfigs)
            {
                // Create the initial contract type
                LoggingUtil.LogVerbose(this, "Pre-load for node: '" + contractConfig.GetValue("name") + "'");
                try
                {
                    new ContractType(contractConfig.GetValue("name"));
                }
                catch (ArgumentException)
                {
                    LoggingUtil.LogError(this, "Couldn't load CONTRACT_TYPE '" + contractConfig.GetValue("name") + "' due to a duplicate name.");
                }
            }

            // Second pass - do the actual loading of details
            foreach (ConfigNode contractConfig in contractConfigs)
            {
                attemptedContracts++;
                yield return(new WaitForEndOfFrame());

                // Fetch the contractType
                string       name         = contractConfig.GetValue("name");
                ContractType contractType = ContractType.GetContractType(name);
                if (contractType != null && !contractType.loaded)
                {
                    // Perform the load
                    try
                    {
                        contractType.Load(contractConfig);
                        if (contractType.enabled)
                        {
                            successContracts++;
                        }
                    }
                    catch (Exception e)
                    {
                        LoggingUtil.LogException(e);
                    }
                }
            }

            LoggingUtil.LogInfo(this, "Loaded " + successContracts + " out of " + totalContracts + " CONTRACT_TYPE nodes.");

            // Check for empty groups and warn
            foreach (ContractGroup group in ContractGroup.contractGroups.Values.Where(g => g != null))
            {
                group.CheckEmpty();
            }

            // Load other things
            MissionControlUI.GroupContainer.LoadConfig();

            // Emit settings for the menu
            SettingsBuilder.EmitSettings();

            if (!reloading && LoggingUtil.logLevel == LoggingUtil.LogLevel.DEBUG || LoggingUtil.logLevel == LoggingUtil.LogLevel.VERBOSE)
            {
                ScreenMessages.PostScreenMessage("Contract Configurator: Loaded " + successContracts + " out of " + totalContracts
                                                 + " contracts successfully.", 5, ScreenMessageStyle.UPPER_CENTER);
            }
        }
Пример #6
0
        /// <summary>
        /// Attempts to parse a value from the config node.  Returns a default value if not found.
        /// Validates return values using the given function.
        /// </summary>
        /// <typeparam name="T">The type of value to convert to.</typeparam>
        /// <param name="configNode">The ConfigNode to read from.</param>
        /// <param name="key">The key to examine.</param>
        /// <param name="setter">Function used to set the output value</param>
        /// <param name="obj">Factory object for error messages.</param>
        /// <param name="defaultValue">Default value to use if there is no key in the config node</param>
        /// <param name="validation">Validation function to run against the returned value</param>
        /// <returns>The parsed value (or default value if not found)</returns>
        public static bool ParseValue <T>(ConfigNode configNode, string key, Action <T> setter, IContractConfiguratorFactory obj, T defaultValue, Func <T, bool> validation)
        {
            // Initialize the data type of the expression
            if (currentDataNode != null && !currentDataNode.IsInitialized(key))
            {
                currentDataNode.BlankInit(key, typeof(T));
            }

            bool valid = true;
            T    value = defaultValue;

            if (configNode.HasValue(key))
            {
                try
                {
                    // Load value
                    value = ParseValue <T>(configNode, key, true);

                    // If value was non-null, run validation
                    if (value != null)
                    {
                        try
                        {
                            valid = validation.Invoke(value);
                            if (!valid)
                            {
                                // In general, the validation function should throw an exception and give a much better message
                                LoggingUtil.LogError(obj, obj.ErrorPrefix(configNode) + ": The value supplied for " + key + " (" + value + ") is invalid.");
                            }
                        }
                        catch (Exception e)
                        {
                            LoggingUtil.LogError(obj, obj.ErrorPrefix(configNode) + ": The value supplied for " + key + " (" + value + ") is invalid.");
                            LoggingUtil.LogException(e);
                            valid = false;
                        }
                    }
                }
                catch (Exception e)
                {
                    if (e.GetType() == typeof(DataNode.ValueNotInitialized))
                    {
                        string dependency = ((DataNode.ValueNotInitialized)e).key;
                        string path       = currentDataNode.Path() + key;

                        LoggingUtil.LogVerbose(typeof(ConfigNodeUtil), "Trying to load " + key + ", but " + dependency + " is uninitialized.");

                        // Defer loading this value
                        DeferredLoadObject <T> loadObj = null;
                        if (!deferredLoads.ContainsKey(path))
                        {
                            deferredLoads[path] = new DeferredLoadObject <T>(configNode, key, setter, obj, validation, currentDataNode);
                        }
                        loadObj = (DeferredLoadObject <T>)deferredLoads[path];

                        // New dependency - try again
                        if (!loadObj.dependencies.Contains(dependency))
                        {
                            LoggingUtil.LogVerbose(typeof(ConfigNodeUtil), "    New dependency, will re-attempt to load later.");
                            loadObj.dependencies.Add(dependency);
                            return(true);
                        }
                    }

                    LoggingUtil.LogError(obj, obj.ErrorPrefix(configNode) + ": Error parsing " + key);
                    LoggingUtil.LogException(e);

                    // Return immediately on deferred load error
                    if (e.GetType() == typeof(DataNode.ValueNotInitialized))
                    {
                        return(false);
                    }

                    valid = false;
                }
                finally
                {
                    AddFoundKey(configNode, key);
                }
            }

            // Store the value
            if (currentDataNode != null)
            {
                LoggingUtil.LogVerbose(typeof(ConfigNodeUtil), "DataNode[" + currentDataNode.Name + "], storing " + key + " = " + value);
                currentDataNode[key] = value;

                if (!currentDataNode.IsDeterministic(key) && initialLoad)
                {
                    currentDataNode.DeferredLoads.Add(new DeferredLoadObject <T>(configNode, key, setter, obj, validation, currentDataNode));
                }
            }

            // Invoke the setter function
            if (valid)
            {
                setter.Invoke(value);
            }

            return(valid);
        }
Пример #7
0
        /*
         * Loads all the contact configuration nodes and creates ContractType objects.
         */
        void LoadContractConfig()
        {
            LoggingUtil.LogDebug(this.GetType(), "Loading CONTRACT_TYPE nodes.");
            ConfigNode[] contractConfigs = GameDatabase.Instance.GetConfigNodes("CONTRACT_TYPE");

            // First pass - create all the ContractType objects
            foreach (ConfigNode contractConfig in contractConfigs)
            {
                totalContracts++;
                LoggingUtil.LogVerbose(this.GetType(), "Pre-load for node: '" + contractConfig.GetValue("name") + "'");
                // Create the initial contract type
                try
                {
                    ContractType contractType = new ContractType(contractConfig.GetValue("name"));
                }
                catch (ArgumentException)
                {
                    LoggingUtil.LogError(this.GetType(), "Couldn't load CONTRACT_TYPE '" + contractConfig.GetValue("name") + "' due to a duplicate name.");

                    // BUG: The same contract will get loaded twice, but just decrement the success counter so one shows as failed
                    successContracts--;
                }
            }

            // Second pass - do the actual loading of details
            foreach (ConfigNode contractConfig in contractConfigs)
            {
                // Fetch the contractType
                string       name         = contractConfig.GetValue("name");
                ContractType contractType = ContractType.contractTypes[name];
                bool         success      = false;
                if (contractType != null)
                {
                    LoggingUtil.LogDebug(this.GetType(), "Loading CONTRACT_TYPE: '" + name + "'");
                    // Perform the load
                    try
                    {
                        if (contractType.Load(contractConfig))
                        {
                            successContracts++;
                            success = true;
                        }
                    }
                    catch (Exception e)
                    {
                        Exception wrapper = new Exception("Error loading CONTRACT_TYPE '" + name + "'", e);
                        Debug.LogException(wrapper);
                    }
                    finally
                    {
                        if (!success)
                        {
                            ContractType.contractTypes.Remove(name);
                        }
                    }
                }
            }

            LoggingUtil.LogInfo(this.GetType(), "Loaded " + successContracts + " out of " + totalContracts + " CONTRACT_TYPE nodes.");

            if (!reloading && LoggingUtil.logLevel == LoggingUtil.LogLevel.DEBUG || LoggingUtil.logLevel == LoggingUtil.LogLevel.VERBOSE)
            {
                ScreenMessages.PostScreenMessage("Contract Configurator: Loaded " + successContracts + " out of " + totalContracts
                                                 + " contracts successfully.", 5, ScreenMessageStyle.UPPER_CENTER);
            }
        }
Пример #8
0
        private IEnumerator <ContractType> ReloadContractTypes()
        {
            reloading = true;

            // Infrom the player of the reload process
            ScreenMessages.PostScreenMessage("Reloading game database...", 2,
                                             ScreenMessageStyle.UPPER_CENTER);
            yield return(null);

            GameDatabase.Instance.Recompile = true;
            GameDatabase.Instance.StartLoad();

            // Wait for the reload
            while (!GameDatabase.Instance.IsReady())
            {
                yield return(null);
            }

            // Attempt to find module manager and do their reload
            var allMM = from loadedAssemblies in AssemblyLoader.loadedAssemblies
                        let assembly = loadedAssemblies.assembly
                                       where assembly.GetName().Name.StartsWith("ModuleManager")
                                       orderby assembly.GetName().Version descending, loadedAssemblies.path ascending
            select loadedAssemblies;

            // Reload module manager
            if (allMM.Count() > 0)
            {
                ScreenMessages.PostScreenMessage("Reloading module manager...", 2,
                                                 ScreenMessageStyle.UPPER_CENTER);

                Assembly mmAssembly = allMM.First().assembly;
                LoggingUtil.LogVerbose(this, "Reloading config using ModuleManager: " + mmAssembly.FullName);

                // Get the module manager object
                Type mmPatchType = mmAssembly.GetType("ModuleManager.MMPatchLoader");
                UnityEngine.Object mmPatchLoader = FindObjectOfType(mmPatchType);

                // Get the methods
                MethodInfo methodStartLoad = mmPatchType.GetMethod("StartLoad", Type.EmptyTypes);
                MethodInfo methodIsReady   = mmPatchType.GetMethod("IsReady");

                // Start the load
                methodStartLoad.Invoke(mmPatchLoader, null);

                // Wait for it to complete
                while (!(bool)methodIsReady.Invoke(mmPatchLoader, null))
                {
                    yield return(null);
                }
            }

            ScreenMessages.PostScreenMessage("Reloading contract types...", 1.5f,
                                             ScreenMessageStyle.UPPER_CENTER);

            // Reload contract configurator
            ClearContractConfig();
            LoadContractConfig();
            AdjustContractTypes();

            // We're done!
            ScreenMessages.PostScreenMessage("Loaded " + successContracts + " out of " + totalContracts
                                             + " contracts successfully.", 5, ScreenMessageStyle.UPPER_CENTER);

            reloading = false;
        }
        public static void RemoveKerbal(ProtoCrewMember pcm)
        {
            LoggingUtil.LogVerbose(typeof(Kerbal), "Removing kerbal " + pcm.name + "...");
            Vessel vessel = FlightGlobals.Vessels.Where(v => v.GetVesselCrew().Contains(pcm)).FirstOrDefault();

            if (vessel != null)
            {
                // If it's an EVA make them disappear...
                if (vessel.isEVA)
                {
                    FlightGlobals.Vessels.Remove(vessel);
                }
                else
                {
                    if (vessel.loaded)
                    {
                        foreach (Part p in vessel.parts)
                        {
                            if (p.protoModuleCrew.Contains(pcm))
                            {
                                // Command seats
                                if (p.partName == "kerbalEVA")
                                {
                                    vessel.parts.Remove(p);
                                }
                                // Everything else
                                else
                                {
                                    LoggingUtil.LogVerbose(typeof(Kerbal), "    Removing " + pcm.name + " from vessel " + vessel.vesselName);
                                    p.RemoveCrewmember(pcm);
                                }
                                break;
                            }
                        }
                    }
                    else
                    {
                        foreach (ProtoPartSnapshot pps in vessel.protoVessel.protoPartSnapshots)
                        {
                            if (pps.HasCrew(pcm.name))
                            {
                                // Command seats
                                if (pps.partName == "kerbalEVA")
                                {
                                    vessel.protoVessel.protoPartSnapshots.Remove(pps);
                                }
                                // Everything else
                                else
                                {
                                    LoggingUtil.LogVerbose(typeof(Kerbal), "    Removing " + pcm.name + " from vessel " + vessel.vesselName);
                                    pps.RemoveCrew(pcm);
                                }
                                break;
                            }
                        }
                    }
                }
            }

            // Remove the kerbal from the roster
            HighLogic.CurrentGame.CrewRoster.Remove(pcm.name);
        }