Beispiel #1
0
        /// <summary>Saves the strings for the selected entities into a new file.</summary>
        /// <param name="parts">The parts to export the strings from.</param>
        /// <param name="assemblies">The mod assemblies to export teh strinsg from.</param>
        void GuiActionExportStrings(IEnumerable <PartsRecord> parts,
                                    IEnumerable <AssemblyRecord> assemblies)
        {
            var partsLocs = parts
                            .SelectMany(x => x.parts)
                            .Select(Extractor.EmitItemsForPart)
                            .SelectMany(x => x)
                            .ToList();
            var modulesLocs = assemblies
                              .SelectMany(x => x.assembly.GetTypes())
                              .Select(Extractor.EmitItemsForType)
                              .SelectMany(x => x)
                              .ToList();

            Debug.LogWarningFormat("Export {0} parts strings and {1} modules strings",
                                   partsLocs.Count, modulesLocs.Count);
            var locItems = partsLocs.Union(modulesLocs);
            var fileName = "strings.cfg";

            if (assemblies.Count() == 1)
            {
                fileName = assemblies.First().assembly.GetName().Name + "_" + fileName;
            }
            var filePath = KspPaths.GetModsDataFilePath(this, "Lang/" + fileName);

            Directory.CreateDirectory(Path.GetDirectoryName(filePath));
            ConfigStore.WriteLocItems(locItems, Localizer.CurrentLanguage, filePath);
            Debug.LogWarningFormat("Strings are written into: {0}", filePath);
            ShowCompletionDialog(StringsExportedDlgTitle, FileSavedTxt.Format(filePath));
        }
Beispiel #2
0
        /// <summary>Reads values of the annotated persistent fields from a config file.</summary>
        /// <param name="filePath">
        /// A relative or an absolute path to the file. It's resolved via
        /// <see cref="KspPaths.MakeAbsPathForGameData"/>.
        /// </param>
        /// <param name="type">A type to load fields for.</param>
        /// <param name="instance">
        /// An instance of type <paramref name="type"/>. If it's <c>null</c> then
        /// only static fields will be loaded.
        /// </param>
        /// <param name="nodePath">
        /// An optional path in the file. All type's field will be read relative to this part.
        /// </param>
        /// <param name="group">A group tag (see <see cref="BasePersistentFieldAttribute"/>).</param>
        /// <seealso cref="PersistentFieldAttribute"/>
        public static void ReadFieldsFromFile(string filePath, Type type, object instance,
                                              string nodePath = null,
                                              string group    = StdPersistentGroups.Default)
        {
            DebugEx.Fine("Loading persistent fields: file={0}, group=\"{1}\"",
                         KspPaths.MakeRelativePathToGameData(filePath), group ?? "<ALL>");
            var node = ConfigNode.Load(KspPaths.MakeAbsPathForGameData(filePath));

            if (node != null && nodePath.Length > 0)
            {
                node = node.GetNode(nodePath);
            }
            if (node != null)
            {
                ReadFieldsFromNode(node, type, instance, group: group);
            }
        }
Beispiel #3
0
        /// <summary>Reads values of the annotated persistent fields from a config file.</summary>
        /// <param name="filePath">A relative or an absolute path to the file. It's resolved via
        /// <see cref="KspPaths.makePluginPath"/>.</param>
        /// <param name="type">A type to load fields for.</param>
        /// <param name="instance">An instance of type <paramref name="type"/>. If it's <c>null</c> then
        /// only static fields will be loaded.</param>
        /// <param name = "nodePath">An optional path in the file. All type's field will be read relative
        /// to this part.</param>
        /// <param name="group">A group tag (see <see cref="AbstractPersistentFieldAttribute"/>).</param>
        /// <seealso cref="PersistentFieldAttribute"/>
        public static void ReadFieldsFromFile(string filePath, Type type, object instance,
                                              string nodePath = null,
                                              string group    = StdPersistentGroups.Default)
        {
            Logger.logInfo("Loading persistent fields: file={0}, group=\"{1}\"",
                           filePath, group ?? "<ALL>");
            var node = ConfigNode.Load(KspPaths.makePluginPath(filePath));

            if (node != null && nodePath.Length > 0)
            {
                node = node.GetNode(nodePath);
            }
            if (node != null)
            {
                ReadFieldsFromNode(node, type, instance, group: group);
            }
        }
Beispiel #4
0
        void Awake()
        {
            if (!KASAPI.isLoaded)
            {
                KASAPI.JointUtils       = new KASImpl.JointUtilsImpl();
                KASAPI.AttachNodesUtils = new KASImpl.AttachNodesUtilsImpl();
                KASAPI.LinkUtils        = new KASImpl.LinkUtilsImpl();
                KASAPI.PhysicsUtils     = new KASImpl.PhysicsUtilsImpl();
                KASAPI.CommonConfig     = new KASImpl.CommonConfigImpl();
                KASAPI.KasEvents        = new KASImpl.KasEventsImpl();
                KASAPI.isLoaded         = true;

                var assembly = GetType().Assembly;
                DebugEx.Info("Loading KAS API v2 from: {0} (v{1})",
                             KspPaths.MakeRelativePathToGameData(assembly.Location),
                             assembly.GetName().Version);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Writes persistent fields into the config files specified by the class annotation.
        /// </summary>
        /// <remarks>Method updates the config file(s) by preserving top level nodes that are not
        /// specified as targets for the requested group.
        /// <para>Note, that fields cannot be writtent into database. Such annotations will be skipped
        /// during the save.</para>
        /// </remarks>
        /// <param name="type">A type to write fields for.</param>
        /// <param name="instance">An instance of type <paramref name="type"/>. If it's <c>null</c> then
        /// only static fields will be written.</param>
        /// <param name="group">A group to write fields for. If <c>null</c> then all groups that are
        /// defined in the class annotation via <see cref="PersistentFieldsFileAttribute"/> will be
        /// written.</param>
        /// <seealso cref="PersistentFieldAttribute"/>
        /// <seealso cref="PersistentFieldsFileAttribute"/>
        public static void WriteFieldsFromType(Type type, object instance,
                                               string group = StdPersistentGroups.Default)
        {
            var attributes = GetPersistentFieldsFiles(type, group);

            DebugEx.Fine("Writing persistent fields: type={0}, group=\"{1}\"", type, group ?? "<ALL>");
            foreach (var attr in attributes)
            {
                if (attr.configFilePath.Length > 0)
                {
                    WriteFieldsIntoFile(KspPaths.MakeAbsPathForGameData(attr.configFilePath), type, instance,
                                        rootNodePath: attr.nodePath, mergeMode: true, group: attr.group);
                }
                else
                {
                    DebugEx.Fine("Not saving database group: {0}", attr.nodePath);
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Patches the part configs so that they refer the tags for the localizable fileds, and saves the
        /// modified fiels in the export location.
        /// </summary>
        /// <remarks></remarks>
        /// <param name="parts">The parts to patch.</param>
        void GuiExportPartConfigs(IEnumerable <PartsRecord> parts)
        {
            var exportParts = parts.SelectMany(x => x.parts);
            var exportPath  = KspPaths.GetModsDataFilePath(this, "Parts/");

            foreach (var part in exportParts)
            {
                var config = ConfigStore.LoadConfigWithComments(
                    part.configFileFullName, localizeValues: false);
                if (config == null)
                {
                    Debug.LogErrorFormat(
                        "Cannot load config file for part {0}: {1}", part.name, part.configFileFullName);
                    continue;
                }
                var partNode = config.GetNode("PART");
                foreach (var fieldName in Extractor.localizablePartFields)
                {
                    var field = partNode.values.Cast <ConfigNode.Value>()
                                .FirstOrDefault(x => x.name == fieldName);
                    if (field == null)
                    {
                        Debug.LogWarningFormat("Field '{0}' is not found in the part {1} config",
                                               fieldName, part.name);
                        continue;
                    }
                    if (field.value.StartsWith("#", StringComparison.Ordinal))
                    {
                        continue; // It's already localized.
                    }
                    var locTag = Extractor.MakePartFieldLocalizationTag(part.name, fieldName);
                    field.comment = locTag + " = " + field.value;
                    field.value   = locTag;
                }

                var tgtPath = exportPath + part.name.Replace(".", "_") + ".cfg";
                Debug.LogWarningFormat("Saving patched part config into: {0}", tgtPath);
                ConfigStore.SaveConfigWithComments(config, tgtPath);
            }
            ShowCompletionDialog(
                ConfigSavedDlgTitle,
                ConfigsSavedInFolderTxt.Format(exportParts.Count(), exportPath));
        }
Beispiel #7
0
        void Awake()
        {
            if (loaded)
            {
                gameObject.DestroyGameObject();
                return; // Only let the loader to work once per version.
            }
            loaded = true;

            var assembly = GetType().Assembly;

            assemblyVersionStr = $"{KspPaths.MakeRelativePathToGameData(assembly.Location)} (v{assembly.GetName().Version})";
            DebugEx.Info("Loading KSPDevUtils: {0}", assemblyVersionStr);

            // Install the localization callbacks. The object must not be destroyed.
            DontDestroyOnLoad(gameObject);
            gameObject.AddComponent <LocalizationLoader>();
            gameObject.AddComponent <UISoundPlayer>();
        }
Beispiel #8
0
        /// <summary>Writes values of the annotated persistent fields into a file.</summary>
        /// <remarks>
        /// All persitent values are <b>added</b> into the file provided. I.e. if node had already had a
        /// value being persited then it either overwritten (ordinary fields) or extended (collection
        /// fields).
        /// </remarks>
        /// <param name="filePath">
        /// A relative or an absolute path to the file. It's resolved via
        /// <see cref="KspPaths.MakeAbsPathForGameData"/>.
        /// </param>
        /// <param name="rootNodePath">
        /// A path to the node in the file where the data should be written. If the node already exsists
        /// it will be deleted.
        /// </param>
        /// <param name="type">A type to write fields for.</param>
        /// <param name="instance">
        /// An instance of type <paramref name="type"/>. If it's <c>null</c> then only static fields will
        /// be written.
        /// </param>
        /// <param name="mergeMode">
        /// If <c>true</c> and the file already exists then only will be created.
        /// </param>
        /// <param name="group">A group tag (see <see cref="BasePersistentFieldAttribute"/>).</param>
        /// <seealso cref="PersistentFieldAttribute"/>
        public static void WriteFieldsIntoFile(string filePath,
                                               Type type, object instance,
                                               string rootNodePath = null, bool mergeMode = true,
                                               string group        = StdPersistentGroups.Default)
        {
            DebugEx.Fine("Writing persistent fields: file={0}, group=\"{1}\", isMerging={2}, root={3}",
                         KspPaths.MakeRelativePathToGameData(filePath),
                         group ?? "<ALL>", mergeMode, rootNodePath ?? "/");
            var node = mergeMode
        ? ConfigNode.Load(filePath) ?? new ConfigNode()  // Make empty node if file doesn't exist.
        : new ConfigNode();
            var tagetNode = node;

            if (rootNodePath != null)
            {
                tagetNode = GetNodeByPath(node, rootNodePath, createIfMissing: true);
                tagetNode.ClearData(); // In case of it's an existing node.
            }
            WriteFieldsIntoNode(tagetNode, type, instance, group: group);
            node.Save(KspPaths.MakeAbsPathForGameData(filePath));
        }
Beispiel #9
0
        /// <summary>Saves the strings for the selected entities into a new file.</summary>
        /// <param name="parts">The parts to export the strings from.</param>
        /// <param name="assemblies">The mod assemblies to export teh strinsg from.</param>
        void GuiActionExportStrings(IEnumerable <PartsRecord> parts,
                                    IEnumerable <AssemblyRecord> assemblies)
        {
            var partsLocs = parts
                            .SelectMany(x => x.parts)
                            .Select(Extractor.EmitItemsForPart)
                            .SelectMany(x => x)
                            .ToList();
            var modulesLocs = assemblies
                              .SelectMany(x => x.assembly.GetTypes())
                              .Select(Extractor.EmitItemsForType)
                              .SelectMany(x => x)
                              .ToList();

            Debug.LogWarningFormat("Export {0} parts strings and {1} modules strings",
                                   partsLocs.Count, modulesLocs.Count);
            var locItems = partsLocs.Union(modulesLocs);
            var filename = KspPaths.GetModsDataFilePath(this, "export.cfg", createMissingDirs: true);

            ConfigStore.WriteLocItems(locItems, Localizer.CurrentLanguage, filename);
            Debug.LogWarningFormat("Strings are written into: {0}", filename);
        }
Beispiel #10
0
        /// <summary>Finds all the entities for the prefix, and populates the list.</summary>
        /// <param name="prefix">The prefix to find URL by.</param>
        void GuiActionUpdateTargets(string prefix)
        {
            targets.Clear();
            if (prefix.Length < 3)
            {
                targets.Add(new StubRecord()
                {
                    stubText = TypePrefixToStartTxt,
                });
                return;
            }

            // Find part configs for the prefix.
            targets.AddRange(PartLoader.LoadedPartsList
                             .Where(x => x.partUrl.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                             .OrderBy(x => x.partUrl)
                             .GroupBy(x => {
                var pos = x.partUrl.LastIndexOf("/Parts", StringComparison.OrdinalIgnoreCase);
                return(pos != -1 ? x.partUrl.Substring(0, pos + 6) : x.partUrl.Split('/')[0]);
            })
                             .Select(group => new PartsRecord()
            {
                urlPrefix = group.Key,
                parts     = group.ToList(),
            })
                             .Cast <ScannedRecord>());

            // Find assemblies for the prefix.
            // Utility assemblies of the same version are loaded only once, but they are referred for every
            // URL at which the assembly was found.
            targets.AddRange(AssemblyLoader.loadedAssemblies
                             .Where(x =>
                                    x.url.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) &&
                                    KspPaths.MakeRelativePathToGameData(x.assembly.Location)
                                    .StartsWith(prefix, StringComparison.OrdinalIgnoreCase) &&
                                    (allowNoModulesAssemblies || x.types.Count > 0))
                             .Select(assembly => new AssemblyRecord()
            {
                assembly = assembly.assembly,
                types    = assembly.types.SelectMany(x => x.Value).ToList(),
                url      = assembly.url,
            })
                             .Cast <ScannedRecord>());

            // Find localization files for the prefix.
            targets.AddRange(GameDatabase.Instance.GetConfigs("Localization")
                             .Where(x => x.url.StartsWith(lookupPrefix, StringComparison.OrdinalIgnoreCase) &&
                                    x.config.GetNodes(Localizer.CurrentLanguage).Any())
                             .Select(url => new ConfigRecord()
            {
                url      = url.url,
                filePath = url.parent.fullPath,
                lang     = Localizer.CurrentLanguage,
                node     = url.config.GetNodes(Localizer.CurrentLanguage).FirstOrDefault(),
            })
                             .Cast <ScannedRecord>());

            if (targets.Count == 0)
            {
                targets.Add(new StubRecord()
                {
                    stubText = NothingFoundForPrefixTxt,
                });
            }
        }
Beispiel #11
0
 /// <inheritdoc/>
 public override string ToString()
 {
     return(string.Format(
                "{0}, lang={1} ({2} strings)",
                KspPaths.MakeRelativePathToGameData(url), lang, node.GetValues().Length));
 }
Beispiel #12
0
 /// <inheritdoc/>
 public override string ToString()
 {
     return(string.Format("{0}, v{1} ({2} modules)",
                          KspPaths.MakeRelativePathToGameData(assembly.Location),
                          assembly.GetName().Version, types.Count));
 }
 /// <inheritdoc/>
 public override string ToString() {
   return ConfigRecordTxt.Format(
       KspPaths.MakeRelativePathToGameData(url), lang, node.GetValues().Length);
 }
 /// <inheritdoc/>
 public override string ToString() {
   return AssemblyRecordTxt.Format(
       KspPaths.MakeRelativePathToGameData(assembly.Location),
       assembly.GetName().Version.ToString(), types.Count);
 }