Esempio n. 1
0
        private async void SelectWeaponCategory_Load(object sender, EventArgs e)
        {
            // Build a list of Weapon Categories found in the Weapons file.
            using (new FetchSafelyFromPool <List <ListItem> >(Utils.ListItemListPool, out List <ListItem> lstCategory))
            {
                XPathNavigator objXmlDocument = await XmlManager.LoadXPathAsync("weapons.xml", _objCharacter?.Settings.EnabledCustomDataDirectoryPaths);

                foreach (XPathNavigator objXmlCategory in !string.IsNullOrEmpty(OnlyCategory)
                             ? objXmlDocument.Select("/chummer/categories/category[. = "
                                                     + OnlyCategory.CleanXPath() + ']')
                             : await objXmlDocument.SelectAndCacheExpressionAsync("/chummer/categories/category"))
                {
                    if (!string.IsNullOrEmpty(WeaponType) && objXmlCategory.Value != "Exotic Ranged Weapons")
                    {
                        string strType = (await objXmlCategory.SelectSingleNodeAndCacheExpressionAsync("@type"))?.Value;
                        if (string.IsNullOrEmpty(strType) || strType != WeaponType)
                        {
                            continue;
                        }
                    }

                    string strInnerText = objXmlCategory.Value;
                    lstCategory.Add(new ListItem(strInnerText,
                                                 (await objXmlCategory.SelectSingleNodeAndCacheExpressionAsync("@translate"))?.Value
                                                 ?? strInnerText));
                }

                // Add the Cyberware Category.
                if (lstCategory.Count == 0 && (OnlyCategory == "Cyberware" || OnlyCategory == "Cyberweapon"))
                {
                    lstCategory.Add(new ListItem("Cyberware", await LanguageManager.GetStringAsync("String_Cyberware")));
                }

                switch (lstCategory.Count)
                {
                case 0:
                    ConfirmSelection(string.Empty);
                    break;

                case 1:
                    ConfirmSelection(lstCategory[0].Value.ToString());
                    break;
                }

                await cboCategory.PopulateWithListItemsAsync(lstCategory);

                await cboCategory.DoThreadSafeAsync(x =>
                {
                    // Select the first Skill in the list.
                    if (x.Items.Count > 0)
                    {
                        x.SelectedIndex = 0;
                    }
                });
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Generates a character cache, which prevents us from repeatedly loading XmlNodes or caching a full character.
        /// </summary>
        /// <param name="strFile"></param>
        private async Task <TreeNode> CacheCharacters(string strFile)
        {
            if (!File.Exists(strFile))
            {
                Program.ShowMessageBox(
                    this,
                    string.Format(GlobalSettings.CultureInfo,
                                  await LanguageManager.GetStringAsync("Message_File_Cannot_Be_Accessed"), strFile));
                return(null);
            }

            ThreadSafeList <XPathNavigator> lstCharacterXmlStatblocks = new ThreadSafeList <XPathNavigator>(3);

            try
            {
                try
                {
                    using (ZipArchive zipArchive
                               = ZipFile.Open(strFile, ZipArchiveMode.Read, Encoding.GetEncoding(850)))
                    {
                        // NOTE: Cannot parallelize because ZipFile.Open creates one handle on the entire zip file that gets messed up if we try to get it to read multiple files at once
                        foreach (ZipArchiveEntry entry in zipArchive.Entries)
                        {
                            string strEntryFullName = entry.FullName;
                            if (strEntryFullName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase) &&
                                strEntryFullName.StartsWith("statblocks_xml", StringComparison.Ordinal))
                            {
                                // If we run into any problems loading the character cache, fail out early.
                                try
                                {
                                    using (StreamReader sr = new StreamReader(entry.Open(), true))
                                    {
                                        await Task.Run(() =>
                                        {
                                            XPathDocument xmlSourceDoc;
                                            using (XmlReader objXmlReader
                                                       = XmlReader.Create(sr, GlobalSettings.SafeXmlReaderSettings))
                                                xmlSourceDoc = new XPathDocument(objXmlReader);
                                            XPathNavigator objToAdd = xmlSourceDoc.CreateNavigator();
                                            lstCharacterXmlStatblocks.Add(objToAdd);
                                        });
                                    }
                                }
                                // If we run into any problems loading the character cache, fail out early.
                                catch (IOException)
                                {
                                    Utils.BreakIfDebug();
                                }
                                catch (XmlException)
                                {
                                    Utils.BreakIfDebug();
                                }
                            }
                            else if (strEntryFullName.StartsWith("images", StringComparison.Ordinal) &&
                                     strEntryFullName.Contains('.'))
                            {
                                string strKey = Path.GetFileName(strEntryFullName);
                                using (Bitmap bmpMugshot = new Bitmap(entry.Open(), true))
                                {
                                    Bitmap bmpNewMugshot = bmpMugshot.PixelFormat == PixelFormat.Format32bppPArgb
                                        ? bmpMugshot.Clone() as Bitmap // Clone makes sure file handle is closed
                                        : bmpMugshot.ConvertPixelFormat(PixelFormat.Format32bppPArgb);
                                    while (!await _dicImages.TryAddAsync(strKey, bmpNewMugshot))
                                    {
                                        (bool blnSuccess, Bitmap bmpOldMugshot) =
                                            await _dicImages.TryRemoveAsync(strKey);

                                        if (blnSuccess)
                                        {
                                            bmpOldMugshot?.Dispose();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                catch (IOException)
                {
                    Program.ShowMessageBox(
                        this,
                        string.Format(GlobalSettings.CultureInfo,
                                      await LanguageManager.GetStringAsync("Message_File_Cannot_Be_Accessed"),
                                      strFile));
                    return(null);
                }
                catch (NotSupportedException)
                {
                    Program.ShowMessageBox(
                        this,
                        string.Format(GlobalSettings.CultureInfo,
                                      await LanguageManager.GetStringAsync("Message_File_Cannot_Be_Accessed"),
                                      strFile));
                    return(null);
                }
                catch (UnauthorizedAccessException)
                {
                    Program.ShowMessageBox(
                        this, await LanguageManager.GetStringAsync("Message_Insufficient_Permissions_Warning"));
                    return(null);
                }

                string strFileText
                    = await strFile.CheapReplaceAsync(Utils.GetStartupPath, () => '<' + Application.ProductName + '>');

                TreeNode nodRootNode = new TreeNode
                {
                    Text        = strFileText,
                    ToolTipText = strFileText
                };

                XPathNavigator xmlMetatypesDocument = await XmlManager.LoadXPathAsync("metatypes.xml");

                foreach (XPathNavigator xmlCharacterDocument in lstCharacterXmlStatblocks)
                {
                    XPathNavigator xmlBaseCharacterNode
                        = xmlCharacterDocument.SelectSingleNode("/document/public/character");
                    if (xmlBaseCharacterNode != null)
                    {
                        HeroLabCharacterCache objCache = new HeroLabCharacterCache
                        {
                            PlayerName = xmlBaseCharacterNode.SelectSingleNode("@playername")?.Value ?? string.Empty
                        };
                        string strNameString = xmlBaseCharacterNode.SelectSingleNode("@name")?.Value ?? string.Empty;
                        objCache.CharacterId = strNameString;
                        if (!string.IsNullOrEmpty(strNameString))
                        {
                            int intAsIndex = strNameString.IndexOf(" as ", StringComparison.Ordinal);
                            if (intAsIndex != -1)
                            {
                                objCache.CharacterName = strNameString.Substring(0, intAsIndex);
                                objCache.CharacterAlias
                                    = strNameString.Substring(intAsIndex).TrimStart(" as ").Trim('\'');
                            }
                            else
                            {
                                objCache.CharacterName = strNameString;
                            }
                        }

                        string strRaceString = xmlBaseCharacterNode.SelectSingleNode("race/@name")?.Value;
                        if (strRaceString == "Metasapient")
                        {
                            strRaceString = "A.I.";
                        }
                        if (!string.IsNullOrEmpty(strRaceString))
                        {
                            foreach (XPathNavigator xmlMetatype in xmlMetatypesDocument.Select(
                                         "/chummer/metatypes/metatype"))
                            {
                                string strMetatypeName = xmlMetatype.SelectSingleNode("name")?.Value ?? string.Empty;
                                if (strMetatypeName == strRaceString)
                                {
                                    objCache.Metatype    = strMetatypeName;
                                    objCache.Metavariant = "None";
                                    break;
                                }

                                foreach (XPathNavigator xmlMetavariant in
                                         await xmlMetatype.SelectAndCacheExpressionAsync("metavariants/metavariant"))
                                {
                                    string strMetavariantName
                                        = xmlMetavariant.SelectSingleNode("name")?.Value ?? string.Empty;
                                    if (strMetavariantName == strRaceString)
                                    {
                                        objCache.Metatype    = strMetatypeName;
                                        objCache.Metavariant = strMetavariantName;
                                        break;
                                    }
                                }
                            }
                        }

                        objCache.Description = xmlBaseCharacterNode.SelectSingleNode("personal/description")?.Value;
                        objCache.Karma       = xmlBaseCharacterNode.SelectSingleNode("karma/@total")?.Value ?? "0";
                        objCache.Essence     = xmlBaseCharacterNode
                                               .SelectSingleNode("attributes/attribute[@name = \"Essence\"]/@text")?.Value;
                        objCache.BuildMethod
                            = xmlBaseCharacterNode.SelectSingleNode("creation/bp/@total")?.ValueAsInt <= 100
                                ? CharacterBuildMethod.Priority
                                : CharacterBuildMethod.Karma;

                        string strSettingsSummary =
                            xmlBaseCharacterNode.SelectSingleNode("settings/@summary")?.Value;
                        if (!string.IsNullOrEmpty(strSettingsSummary))
                        {
                            int  intSemicolonIndex;
                            bool blnDoFullHouse = false;
                            int  intSourcebooksIndex
                                = strSettingsSummary.IndexOf("Core Rulebooks:", StringComparison.OrdinalIgnoreCase);
                            if (intSourcebooksIndex != -1)
                            {
                                intSemicolonIndex = strSettingsSummary.IndexOf(';', intSourcebooksIndex);
                                if (intSourcebooksIndex + 16 < intSemicolonIndex)
                                {
                                    blnDoFullHouse
                                        = true; // We probably have multiple books enabled, so use Full House instead
                                }
                            }

                            string strHeroLabSettingsName = "Standard";

                            int intCharCreationSystemsIndex =
                                strSettingsSummary.IndexOf("Character Creation Systems:",
                                                           StringComparison.OrdinalIgnoreCase);
                            if (intCharCreationSystemsIndex != -1)
                            {
                                intSemicolonIndex = strSettingsSummary.IndexOf(';', intCharCreationSystemsIndex);
                                if (intCharCreationSystemsIndex + 28 <= intSemicolonIndex)
                                {
                                    strHeroLabSettingsName = strSettingsSummary.Substring(
                                        intCharCreationSystemsIndex + 28,
                                        strSettingsSummary.IndexOf(
                                            ';', intCharCreationSystemsIndex)
                                        - 28 - intCharCreationSystemsIndex)
                                                             .Trim();
                                    if (strHeroLabSettingsName == "Established Runners")
                                    {
                                        strHeroLabSettingsName = "Standard";
                                    }
                                }
                            }

                            if (strHeroLabSettingsName == "Standard")
                            {
                                if (blnDoFullHouse)
                                {
                                    strHeroLabSettingsName = objCache.BuildMethod == CharacterBuildMethod.Karma
                                        ? "Full House (Point Buy)"
                                        : "Full House";
                                }
                                else if (objCache.BuildMethod == CharacterBuildMethod.Karma)
                                {
                                    strHeroLabSettingsName = "Point Buy";
                                }
                            }

                            objCache.SettingsName = strHeroLabSettingsName;
                        }

                        objCache.Created = objCache.Karma != "0";
                        if (!objCache.Created)
                        {
                            XPathNodeIterator xmlJournalEntries
                                = await xmlBaseCharacterNode.SelectAndCacheExpressionAsync("journals/journal");

                            if (xmlJournalEntries?.Count > 1)
                            {
                                objCache.Created = true;
                            }
                            else if (xmlJournalEntries?.Count == 1 &&
                                     xmlJournalEntries.Current?.SelectSingleNode("@name")?.Value != "Title")
                            {
                                objCache.Created = true;
                            }
                        }

                        string strImageString = xmlBaseCharacterNode.SelectSingleNode("images/image/@filename")?.Value;
                        if (!string.IsNullOrEmpty(strImageString))
                        {
                            (bool blnSuccess, Bitmap objTemp) = await _dicImages.TryGetValueAsync(strImageString);

                            if (blnSuccess)
                            {
                                objCache.Mugshot = objTemp;
                            }
                        }

                        objCache.FilePath = strFile;
                        TreeNode objNode = new TreeNode
                        {
                            Text        = await CalculatedName(objCache),
                            ToolTipText = await strFile.CheapReplaceAsync(Utils.GetStartupPath,
                                                                          () => '<' + Application.ProductName + '>')
                        };
                        nodRootNode.Nodes.Add(objNode);

                        await _lstCharacterCache.AddAsync(objCache);

                        objNode.Tag = await _lstCharacterCache.IndexOfAsync(objCache);
                    }
                }

                nodRootNode.Expand();
                return(nodRootNode);
            }
            finally
            {
                await lstCharacterXmlStatblocks.DisposeAsync();
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Update the labels and images based on the selected treenode.
        /// </summary>
        /// <param name="objCache"></param>
        private async Task UpdateCharacter(HeroLabCharacterCache objCache)
        {
            if (objCache != null)
            {
                await txtCharacterBio.DoThreadSafeAsync(x => x.Text = objCache.Description);

                string strUnknown = await LanguageManager.GetStringAsync("String_Unknown");

                await lblCharacterName.DoThreadSafeAsync(x =>
                {
                    x.Text = objCache.CharacterName;
                    if (string.IsNullOrEmpty(x.Text))
                    {
                        x.Text = strUnknown;
                    }
                    x.Visible = true;
                });

                await lblCharacterNameLabel.DoThreadSafeAsync(x => x.Visible = true);

                await lblCharacterAlias.DoThreadSafeAsync(x =>
                {
                    x.Text = objCache.CharacterAlias;
                    if (string.IsNullOrEmpty(x.Text))
                    {
                        x.Text = strUnknown;
                    }
                    x.Visible = true;
                });

                await lblCharacterAliasLabel.DoThreadSafeAsync(x => x.Visible = true);

                await lblPlayerName.DoThreadSafeAsync(x =>
                {
                    x.Text = objCache.PlayerName;
                    if (string.IsNullOrEmpty(x.Text))
                    {
                        x.Text = strUnknown;
                    }
                    x.Visible = true;
                });

                await lblPlayerNameLabel.DoThreadSafeAsync(x => x.Visible = true);

                string strNone = await LanguageManager.GetStringAsync("String_None");

                await lblCareerKarma.DoThreadSafeAsync(x =>
                {
                    x.Text = objCache.Karma;
                    if (string.IsNullOrEmpty(x.Text) || x.Text == 0.ToString(GlobalSettings.CultureInfo))
                    {
                        x.Text = strNone;
                    }
                    x.Visible = true;
                });

                await lblCareerKarmaLabel.DoThreadSafeAsync(x => x.Visible = true);

                await lblEssence.DoThreadSafeAsync(x =>
                {
                    x.Text = objCache.Essence;
                    if (string.IsNullOrEmpty(x.Text))
                    {
                        x.Text = strUnknown;
                    }
                    x.Visible = true;
                });

                await lblEssenceLabel.DoThreadSafeAsync(x => x.Visible = true);

                await picMugshot.DoThreadSafeAsync(x => x.Image = objCache.Mugshot);

                // Populate character information fields.
                XPathNavigator objMetatypeDoc = await XmlManager.LoadXPathAsync("metatypes.xml");

                XPathNavigator objMetatypeNode = objMetatypeDoc.SelectSingleNode("/chummer/metatypes/metatype[name = " + objCache.Metatype.CleanXPath() + ']');
                if (objMetatypeNode == null)
                {
                    objMetatypeDoc = await XmlManager.LoadXPathAsync("critters.xml");

                    objMetatypeNode = objMetatypeDoc.SelectSingleNode("/chummer/metatypes/metatype[name = " + objCache.Metatype.CleanXPath() + ']');
                }

                string strMetatype = objMetatypeNode != null
                    ? (await objMetatypeNode.SelectSingleNodeAndCacheExpressionAsync("translate"))?.Value
                                     ?? objCache.Metatype
                    : objCache.Metatype;

                if (!string.IsNullOrEmpty(objCache.Metavariant) && objCache.Metavariant != "None")
                {
                    objMetatypeNode = objMetatypeNode?.SelectSingleNode("metavariants/metavariant[name = " + objCache.Metavariant.CleanXPath() + ']');

                    strMetatype += " (" + (objMetatypeNode != null
                        ? (await objMetatypeNode.SelectSingleNodeAndCacheExpressionAsync("translate"))?.Value
                                           ?? objCache.Metavariant
                        : objCache.Metavariant) + ')';
                }

                await lblMetatype.DoThreadSafeAsync(x =>
                {
                    x.Text = strMetatype;
                    if (string.IsNullOrEmpty(x.Text))
                    {
                        x.Text = strUnknown;
                    }
                    x.Visible = true;
                });

                await lblMetatypeLabel.DoThreadSafeAsync(x => x.Visible = true);

                await cmdImport.DoThreadSafeAsync(x => x.Enabled = true);
            }
            else
            {
                await txtCharacterBio.DoThreadSafeAsync(x => x.Text = string.Empty);

                await lblCharacterNameLabel.DoThreadSafeAsync(x => x.Visible = false);

                await lblCharacterName.DoThreadSafeAsync(x => x.Visible = false);

                await lblCharacterAliasLabel.DoThreadSafeAsync(x => x.Visible = false);

                await lblCharacterAlias.DoThreadSafeAsync(x => x.Visible = false);

                await lblPlayerNameLabel.DoThreadSafeAsync(x => x.Visible = false);

                await lblPlayerName.DoThreadSafeAsync(x => x.Visible = false);

                await lblMetatypeLabel.DoThreadSafeAsync(x => x.Visible = false);

                await lblMetatype.DoThreadSafeAsync(x => x.Visible = false);

                await lblCareerKarmaLabel.DoThreadSafeAsync(x => x.Visible = false);

                await lblCareerKarma.DoThreadSafeAsync(x => x.Visible = false);

                await lblEssenceLabel.DoThreadSafeAsync(x => x.Visible = false);

                await lblEssence.DoThreadSafeAsync(x => x.Visible = false);

                await picMugshot.DoThreadSafeAsync(x => x.Image = null);

                await cmdImport.DoThreadSafeAsync(x => x.Enabled = false);
            }

            await ProcessMugshot();
        }
Esempio n. 4
0
        private async ValueTask LoadContent()
        {
            using (CustomActivity opLoadMasterindex = Timekeeper.StartSyncron("op_load_frm_masterindex", null,
                                                                              CustomActivity.OperationType.RequestOperation, null))
            {
                _dicCachedNotes.Clear();
                foreach (MasterIndexEntry objExistingEntry in _lstItems.Select(x => x.Value))
                {
                    objExistingEntry.Dispose();
                }
                _lstItems.Clear();
                _lstFileNamesWithItems.Clear();
                string strSourceFilter;
                using (new FetchSafelyFromPool <HashSet <string> >(Utils.StringHashSetPool,
                                                                   out HashSet <string> setValidCodes))
                {
                    foreach (XPathNavigator xmlBookNode in (await XmlManager.LoadXPathAsync(
                                                                "books.xml", _objSelectedSetting.EnabledCustomDataDirectoryPaths))
                             .SelectAndCacheExpression("/chummer/books/book/code"))
                    {
                        setValidCodes.Add(xmlBookNode.Value);
                    }

                    setValidCodes.IntersectWith(_objSelectedSetting.Books);

                    strSourceFilter = setValidCodes.Count > 0
                        ? '(' + string.Join(" or ", setValidCodes.Select(x => "source = " + x.CleanXPath())) + ')'
                        : "source";
                }

                using (_ = Timekeeper.StartSyncron("load_frm_masterindex_load_andpopulate_entries",
                                                   opLoadMasterindex))
                {
                    ConcurrentBag <ListItem> lstItemsForLoading = new ConcurrentBag <ListItem>();
                    using (_ = Timekeeper.StartSyncron("load_frm_masterindex_load_entries", opLoadMasterindex))
                    {
                        ConcurrentBag <ListItem> lstFileNamesWithItemsForLoading = new ConcurrentBag <ListItem>();
                        // Prevents locking the UI thread while still benefitting from static scheduling of Parallel.ForEach
                        await Task.WhenAll(_astrFileNames.Select(strFileName => Task.Run(async() =>
                        {
                            XPathNavigator xmlBaseNode
                                = await XmlManager.LoadXPathAsync(strFileName,
                                                                  _objSelectedSetting.EnabledCustomDataDirectoryPaths);
                            xmlBaseNode = xmlBaseNode.SelectSingleNodeAndCacheExpression("/chummer");
                            if (xmlBaseNode == null)
                            {
                                return;
                            }
                            bool blnLoopFileNameHasItems = false;
                            foreach (XPathNavigator xmlItemNode in xmlBaseNode.SelectAndCacheExpression(
                                         ".//*[page and " +
                                         strSourceFilter + ']'))
                            {
                                blnLoopFileNameHasItems = true;
                                string strName          = xmlItemNode.SelectSingleNodeAndCacheExpression("name")?.Value;
                                string strDisplayName
                                    = xmlItemNode.SelectSingleNodeAndCacheExpression("translate")?.Value
                                      ?? strName
                                      ?? xmlItemNode.SelectSingleNodeAndCacheExpression("id")?.Value
                                      ?? await LanguageManager.GetStringAsync("String_Unknown");
                                string strSource      = xmlItemNode.SelectSingleNodeAndCacheExpression("source")?.Value;
                                string strPage        = xmlItemNode.SelectSingleNodeAndCacheExpression("page")?.Value;
                                string strDisplayPage = xmlItemNode.SelectSingleNodeAndCacheExpression("altpage")?.Value
                                                        ?? strPage;
                                string strEnglishNameOnPage
                                    = xmlItemNode.SelectSingleNodeAndCacheExpression("nameonpage")?.Value
                                      ?? strName;
                                string strTranslatedNameOnPage =
                                    xmlItemNode.SelectSingleNodeAndCacheExpression("altnameonpage")?.Value
                                    ?? strDisplayName;
                                string strNotes = xmlItemNode.SelectSingleNodeAndCacheExpression("altnotes")?.Value
                                                  ?? xmlItemNode.SelectSingleNodeAndCacheExpression("notes")?.Value;
                                MasterIndexEntry objEntry = new MasterIndexEntry(
                                    strDisplayName,
                                    strFileName,
                                    new SourceString(strSource, strPage, GlobalSettings.DefaultLanguage,
                                                     GlobalSettings.InvariantCultureInfo),
                                    new SourceString(strSource, strDisplayPage, GlobalSettings.Language,
                                                     GlobalSettings.CultureInfo),
                                    strEnglishNameOnPage,
                                    strTranslatedNameOnPage);
                                lstItemsForLoading.Add(new ListItem(objEntry, strDisplayName));
                                if (!string.IsNullOrEmpty(strNotes))
                                {
                                    _dicCachedNotes.TryAdd(objEntry, strNotes);
                                }
                            }

                            if (blnLoopFileNameHasItems)
                            {
                                lstFileNamesWithItemsForLoading.Add(new ListItem(strFileName, strFileName));
                            }
                        })));

                        _lstFileNamesWithItems.AddRange(lstFileNamesWithItemsForLoading);
                    }

                    using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_entries", opLoadMasterindex))
                    {
                        string strSpace = await LanguageManager.GetStringAsync("String_Space");

                        string strFormat = "{0}" + strSpace + "[{1}]";
                        Dictionary <string, List <ListItem> > dicHelper
                            = new Dictionary <string, List <ListItem> >(lstItemsForLoading.Count);
                        try
                        {
                            foreach (ListItem objItem in lstItemsForLoading)
                            {
                                if (!(objItem.Value is MasterIndexEntry objEntry))
                                {
                                    continue;
                                }
                                string strKey = objEntry.DisplayName.ToUpperInvariant();
                                if (dicHelper.TryGetValue(strKey, out List <ListItem> lstExistingItems))
                                {
                                    ListItem objExistingItem = lstExistingItems.Find(
                                        x => x.Value is MasterIndexEntry y &&
                                        objEntry.DisplaySource.Equals(y.DisplaySource));
                                    if (objExistingItem.Value is MasterIndexEntry objLoopEntry)
                                    {
                                        objLoopEntry.FileNames.UnionWith(objEntry.FileNames);
                                        objEntry.Dispose();
                                    }
                                    else
                                    {
                                        using (new FetchSafelyFromPool <List <ListItem> >(
                                                   Utils.ListItemListPool, out List <ListItem> lstItemsNeedingNameChanges))
                                        {
                                            lstItemsNeedingNameChanges.AddRange(lstExistingItems.FindAll(
                                                                                    x => x.Value is MasterIndexEntry y &&
                                                                                    !objEntry.FileNames.IsSubsetOf(y.FileNames)));
                                            if (lstItemsNeedingNameChanges.Count == 0)
                                            {
                                                _lstItems.Add(
                                                    objItem); // Not using AddRange because of potential memory issues
                                                lstExistingItems.Add(objItem);
                                            }
                                            else
                                            {
                                                ListItem objItemToAdd = new ListItem(
                                                    objItem.Value, string.Format(GlobalSettings.CultureInfo,
                                                                                 strFormat, objItem.Name,
                                                                                 string.Join(
                                                                                     ',' + strSpace, objEntry.FileNames)));
                                                _lstItems.Add(
                                                    objItemToAdd); // Not using AddRange because of potential memory issues
                                                lstExistingItems.Add(objItemToAdd);

                                                foreach (ListItem objToRename in lstItemsNeedingNameChanges)
                                                {
                                                    _lstItems.Remove(objToRename);
                                                    lstExistingItems.Remove(objToRename);

                                                    if (!(objToRename.Value is MasterIndexEntry objExistingEntry))
                                                    {
                                                        continue;
                                                    }
                                                    objItemToAdd = new ListItem(objToRename.Value, string.Format(
                                                                                    GlobalSettings.CultureInfo,
                                                                                    strFormat, objExistingEntry.DisplayName,
                                                                                    string.Join(
                                                                                        ',' + strSpace,
                                                                                        objExistingEntry.FileNames)));
                                                    _lstItems.Add(
                                                        objItemToAdd); // Not using AddRange because of potential memory issues
                                                    lstExistingItems.Add(objItemToAdd);
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    _lstItems.Add(objItem); // Not using AddRange because of potential memory issues
                                    List <ListItem> lstHelperItems = Utils.ListItemListPool.Get();
                                    lstHelperItems.Add(objItem);
                                    dicHelper.Add(strKey, lstHelperItems);
                                }
                            }
                        }
                        finally
                        {
                            foreach (List <ListItem> lstHelperItems in dicHelper.Values)
                            {
                                Utils.ListItemListPool.Return(lstHelperItems);
                            }
                        }
                    }
                }

                using (_ = Timekeeper.StartSyncron("load_frm_masterindex_sort_entries", opLoadMasterindex))
                {
                    _lstItems.Sort(CompareListItems.CompareNames);
                    _lstFileNamesWithItems.Sort(CompareListItems.CompareNames);
                }

                using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_controls", opLoadMasterindex))
                {
                    _lstFileNamesWithItems.Insert(0, new ListItem(string.Empty, await LanguageManager.GetStringAsync("String_All")));

                    int intOldSelectedIndex = cboFile.SelectedIndex;

                    cboFile.BeginUpdate();
                    cboFile.PopulateWithListItems(_lstFileNamesWithItems);
                    try
                    {
                        cboFile.SelectedIndex = Math.Max(intOldSelectedIndex, 0);
                    }
                    // For some reason, some unit tests will fire this exception even when _lstFileNamesWithItems is explicitly checked for having enough items
                    catch (ArgumentOutOfRangeException)
                    {
                        cboFile.SelectedIndex = -1;
                    }
                    cboFile.EndUpdate();

                    lstItems.BeginUpdate();
                    lstItems.PopulateWithListItems(_lstItems);
                    lstItems.SelectedIndex = -1;
                    lstItems.EndUpdate();

                    _blnSkipRefresh = false;
                }
            }
        }
Esempio n. 5
0
        private async void frmMasterIndex_Load(object sender, EventArgs e)
        {
            using (var op_load_frm_masterindex = Timekeeper.StartSyncron("op_load_frm_masterindex", null, CustomActivity.OperationType.RequestOperation, null))
            {
                HashSet <string> setValidCodes = new HashSet <string>();
                foreach (XPathNavigator xmlBookNode in (await XmlManager.LoadXPathAsync("books.xml")).Select("/chummer/books/book/code"))
                {
                    setValidCodes.Add(xmlBookNode.Value);
                }

                string strSourceFilter = setValidCodes.Count > 0
                    ? new StringBuilder("(")
                                         .AppendJoin(" or ", setValidCodes.Select(x => "source = \'" + x + "\'"))
                                         .Append(')').ToString()
                    : "source";

                ConcurrentBag <ListItem> lstItemsForLoading = new ConcurrentBag <ListItem>();
                ConcurrentBag <ListItem> lstFileNamesWithItemsForLoading = new ConcurrentBag <ListItem>();
                using (_ = Timekeeper.StartSyncron("load_frm_masterindex_load_entries", op_load_frm_masterindex))
                {
                    // Prevents locking the UI thread while still benefitting from static scheduling of Parallel.ForEach
                    await Task.Run(() =>
                    {
                        Parallel.ForEach(_lstFileNames, strFileName =>
                        {
                            XPathNavigator xmlBaseNode = XmlManager.LoadXPath(strFileName);
                            xmlBaseNode = xmlBaseNode.SelectSingleNode("/chummer");
                            if (xmlBaseNode == null)
                            {
                                return;
                            }
                            bool blnLoopFileNameHasItems = false;
                            foreach (XPathNavigator xmlItemNode in xmlBaseNode.Select(".//*[page and " +
                                                                                      strSourceFilter + ']'))
                            {
                                blnLoopFileNameHasItems = true;
                                string strName          = xmlItemNode.SelectSingleNode("name")?.Value;
                                string strDisplayName   = xmlItemNode.SelectSingleNode("translate")?.Value
                                                          ?? strName
                                                          ?? xmlItemNode.SelectSingleNode("id")?.Value
                                                          ?? LanguageManager.GetString("String_Unknown");
                                string strSource      = xmlItemNode.SelectSingleNode("source")?.Value;
                                string strPage        = xmlItemNode.SelectSingleNode("page")?.Value;
                                string strDisplayPage = xmlItemNode.SelectSingleNode("altpage")?.Value
                                                        ?? strPage;
                                string strEnglishNameOnPage = xmlItemNode.SelectSingleNode("nameonpage")?.Value
                                                              ?? strName;
                                string strTranslatedNameOnPage =
                                    xmlItemNode.SelectSingleNode("altnameonpage")?.Value
                                    ?? strDisplayName;
                                string strNotes = xmlItemNode.SelectSingleNode("altnotes")?.Value
                                                  ?? xmlItemNode.SelectSingleNode("notes")?.Value;
                                MasterIndexEntry objEntry = new MasterIndexEntry(
                                    strDisplayName,
                                    strFileName,
                                    new SourceString(strSource, strPage, GlobalOptions.DefaultLanguage,
                                                     GlobalOptions.InvariantCultureInfo),
                                    new SourceString(strSource, strDisplayPage, GlobalOptions.Language,
                                                     GlobalOptions.CultureInfo),
                                    strEnglishNameOnPage,
                                    strTranslatedNameOnPage);
                                lstItemsForLoading.Add(new ListItem(objEntry, strDisplayName));
                                if (!string.IsNullOrEmpty(strNotes))
                                {
                                    _dicCachedNotes.TryAdd(objEntry, strNotes);
                                }
                            }

                            if (blnLoopFileNameHasItems)
                            {
                                lstFileNamesWithItemsForLoading.Add(new ListItem(strFileName, strFileName));
                            }
                        });
                    });
                }

                using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_entries", op_load_frm_masterindex))
                {
                    string strSpace  = LanguageManager.GetString("String_Space");
                    string strFormat = "{0}" + strSpace + "[{1}]";
                    Dictionary <string, List <ListItem> > dicHelper = new Dictionary <string, List <ListItem> >(lstItemsForLoading.Count);
                    foreach (ListItem objItem in lstItemsForLoading)
                    {
                        MasterIndexEntry objEntry = (MasterIndexEntry)objItem.Value;
                        string           strKey   = objEntry.DisplayName.ToUpperInvariant();
                        if (dicHelper.TryGetValue(strKey, out List <ListItem> lstExistingItems))
                        {
                            ListItem objExistingItem = lstExistingItems.FirstOrDefault(x =>
                                                                                       objEntry.DisplaySource.Equals(((MasterIndexEntry)x.Value).DisplaySource));
                            if (objExistingItem.Value != null)
                            {
                                ((MasterIndexEntry)objExistingItem.Value).FileNames.UnionWith(objEntry.FileNames);
                            }
                            else
                            {
                                List <ListItem> lstItemsNeedingNameChanges = lstExistingItems.Where(x => !objEntry.FileNames.IsSubsetOf(((MasterIndexEntry)x.Value).FileNames)).ToList();
                                if (lstItemsNeedingNameChanges.Count == 0)
                                {
                                    _lstItems.Add(objItem); // Not using AddRange because of potential memory issues
                                    lstExistingItems.Add(objItem);
                                }
                                else
                                {
                                    ListItem objItemToAdd = new ListItem(objItem.Value, string.Format(GlobalOptions.CultureInfo,
                                                                                                      strFormat, objItem.Name, string.Join(',' + strSpace, objEntry.FileNames)));
                                    _lstItems.Add(objItemToAdd); // Not using AddRange because of potential memory issues
                                    lstExistingItems.Add(objItemToAdd);

                                    foreach (ListItem objToRename in lstItemsNeedingNameChanges)
                                    {
                                        _lstItems.Remove(objToRename);
                                        lstExistingItems.Remove(objToRename);

                                        MasterIndexEntry objExistingEntry = (MasterIndexEntry)objToRename.Value;
                                        objItemToAdd = new ListItem(objToRename.Value, string.Format(GlobalOptions.CultureInfo,
                                                                                                     strFormat, objExistingEntry.DisplayName, string.Join(',' + strSpace, objExistingEntry.FileNames)));
                                        _lstItems.Add(objItemToAdd); // Not using AddRange because of potential memory issues
                                        lstExistingItems.Add(objItemToAdd);
                                    }
                                }
                            }
                        }
                        else
                        {
                            _lstItems.Add(objItem); // Not using AddRange because of potential memory issues
                            dicHelper.Add(strKey, new List <ListItem>(objItem.Yield()));
                        }
                    }
                    _lstFileNamesWithItems.AddRange(lstFileNamesWithItemsForLoading);
                }

                using (_ = Timekeeper.StartSyncron("load_frm_masterindex_sort_entries", op_load_frm_masterindex))
                {
                    _lstItems.Sort(CompareListItems.CompareNames);
                    _lstFileNamesWithItems.Sort(CompareListItems.CompareNames);
                }

                using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_controls", op_load_frm_masterindex))
                {
                    _lstFileNamesWithItems.Insert(0, new ListItem(string.Empty, LanguageManager.GetString("String_All")));

                    cboFile.BeginUpdate();
                    cboFile.PopulateWithListItems(_lstFileNamesWithItems);
                    try
                    {
                        cboFile.SelectedIndex = 0;
                    }
                    // For some reason, some unit tests will fire this exception even when _lstFileNamesWithItems is explicitly checked for having enough items
                    catch (ArgumentOutOfRangeException)
                    {
                        cboFile.SelectedIndex = -1;
                    }
                    cboFile.EndUpdate();

                    lstItems.BeginUpdate();
                    lstItems.PopulateWithListItems(_lstItems);
                    lstItems.SelectedIndex = -1;
                    lstItems.EndUpdate();

                    _blnSkipRefresh = false;
                }
            }
        }
Esempio n. 6
0
        private async void cmdOK_Click(object sender, EventArgs e)
        {
            // Make sure the kit and file name fields are populated.
            string strName = await txtName.DoThreadSafeFuncAsync(x => x.Text);

            if (string.IsNullOrEmpty(strName))
            {
                Program.ShowMessageBox(this, await LanguageManager.GetStringAsync("Message_CreatePACKSKit_KitName"), await LanguageManager.GetStringAsync("MessageTitle_CreatePACKSKit_KitName"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            string strFileName = await txtFileName.DoThreadSafeFuncAsync(x => x.Text);

            if (string.IsNullOrEmpty(strFileName))
            {
                Program.ShowMessageBox(this, await LanguageManager.GetStringAsync("Message_CreatePACKSKit_FileName"), await LanguageManager.GetStringAsync("MessageTitle_CreatePACKSKit_FileName"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // Make sure the file name starts with custom and ends with _packs.xml.
            if (!strFileName.StartsWith("custom_", StringComparison.OrdinalIgnoreCase) || !strFileName.EndsWith("_packs.xml", StringComparison.OrdinalIgnoreCase))
            {
                Program.ShowMessageBox(this, await LanguageManager.GetStringAsync("Message_CreatePACKSKit_InvalidFileName"), await LanguageManager.GetStringAsync("MessageTitle_CreatePACKSKit_InvalidFileName"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // See if a Kit with this name already exists for the Custom category.
            // This was originally done without the XmlManager, but because amends and overrides and toggling custom data directories can change names, we need to use it.
            if ((await XmlManager.LoadXPathAsync("packs.xml", _objCharacter.Settings.EnabledCustomDataDirectoryPaths))
                .SelectSingleNode("/chummer/packs/pack[name = " + strName.CleanXPath() + " and category = \"Custom\"]") != null)
            {
                Program.ShowMessageBox(this, string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Message_CreatePACKSKit_DuplicateName"), strName),
                                       await LanguageManager.GetStringAsync("MessageTitle_CreatePACKSKit_DuplicateName"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            string strPath = Path.Combine(Utils.GetStartupPath, "data", strFileName);

            // If this is not a new file, read in the existing contents.
            XmlDocument objXmlCurrentDocument = null;

            if (File.Exists(strPath))
            {
                try
                {
                    objXmlCurrentDocument = new XmlDocument {
                        XmlResolver = null
                    };
                    objXmlCurrentDocument.LoadStandard(strPath);
                }
                catch (IOException ex)
                {
                    Program.ShowMessageBox(this, ex.ToString());
                    return;
                }
                catch (XmlException ex)
                {
                    Program.ShowMessageBox(this, ex.ToString());
                    return;
                }
            }

            using (FileStream objStream = new FileStream(strPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                using (XmlWriter objWriter = Utils.GetStandardXmlWriter(objStream))
                {
                    await objWriter.WriteStartDocumentAsync();

                    // <chummer>
                    await objWriter.WriteStartElementAsync("chummer");

                    // <packs>
                    await objWriter.WriteStartElementAsync("packs");

                    // If this is not a new file, write out the current contents.
                    if (objXmlCurrentDocument != null)
                    {
                        XmlNode xmlExistingPacksNode = objXmlCurrentDocument.SelectSingleNode("/chummer/packs");
                        xmlExistingPacksNode?.WriteContentTo(objWriter);
                    }

                    // <pack>
                    await objWriter.WriteStartElementAsync("pack");

                    // <name />
                    await objWriter.WriteElementStringAsync("name", txtName.Text);

                    // <category />
                    await objWriter.WriteElementStringAsync("category", "Custom");

                    // Export Attributes.
                    if (await chkAttributes.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        int intBOD      = await _objCharacter.BOD.ValueAsync - (await _objCharacter.BOD.MetatypeMinimumAsync - 1);
                        int intAGI      = await _objCharacter.AGI.ValueAsync - (await _objCharacter.AGI.MetatypeMinimumAsync - 1);
                        int intREA      = await _objCharacter.REA.ValueAsync - (await _objCharacter.REA.MetatypeMinimumAsync - 1);
                        int intSTR      = await _objCharacter.STR.ValueAsync - (await _objCharacter.STR.MetatypeMinimumAsync - 1);
                        int intCHA      = await _objCharacter.CHA.ValueAsync - (await _objCharacter.CHA.MetatypeMinimumAsync - 1);
                        int intINT      = await _objCharacter.INT.ValueAsync - (await _objCharacter.INT.MetatypeMinimumAsync - 1);
                        int intLOG      = await _objCharacter.LOG.ValueAsync - (await _objCharacter.LOG.MetatypeMinimumAsync - 1);
                        int intWIL      = await _objCharacter.WIL.ValueAsync - (await _objCharacter.WIL.MetatypeMinimumAsync - 1);
                        int intEDG      = await _objCharacter.EDG.ValueAsync - (await _objCharacter.EDG.MetatypeMinimumAsync - 1);
                        int intMAG      = await _objCharacter.MAG.ValueAsync - (await _objCharacter.MAG.MetatypeMinimumAsync - 1);
                        int intMAGAdept = await _objCharacter.MAGAdept.ValueAsync - (await _objCharacter.MAGAdept.MetatypeMinimumAsync - 1);
                        int intDEP      = await _objCharacter.DEP.ValueAsync - (await _objCharacter.DEP.MetatypeMinimumAsync - 1);
                        int intRES      = await _objCharacter.RES.ValueAsync - (await _objCharacter.RES.MetatypeMinimumAsync - 1);
                        // <attributes>
                        await objWriter.WriteStartElementAsync("attributes");

                        await objWriter.WriteElementStringAsync("bod", intBOD.ToString(GlobalSettings.InvariantCultureInfo));

                        await objWriter.WriteElementStringAsync("agi", intAGI.ToString(GlobalSettings.InvariantCultureInfo));

                        await objWriter.WriteElementStringAsync("rea", intREA.ToString(GlobalSettings.InvariantCultureInfo));

                        await objWriter.WriteElementStringAsync("str", intSTR.ToString(GlobalSettings.InvariantCultureInfo));

                        await objWriter.WriteElementStringAsync("cha", intCHA.ToString(GlobalSettings.InvariantCultureInfo));

                        await objWriter.WriteElementStringAsync("int", intINT.ToString(GlobalSettings.InvariantCultureInfo));

                        await objWriter.WriteElementStringAsync("log", intLOG.ToString(GlobalSettings.InvariantCultureInfo));

                        await objWriter.WriteElementStringAsync("wil", intWIL.ToString(GlobalSettings.InvariantCultureInfo));

                        await objWriter.WriteElementStringAsync("edg", intEDG.ToString(GlobalSettings.InvariantCultureInfo));

                        if (_objCharacter.MAGEnabled)
                        {
                            await objWriter.WriteElementStringAsync("mag", intMAG.ToString(GlobalSettings.InvariantCultureInfo));

                            if (_objCharacter.Settings.MysAdeptSecondMAGAttribute && _objCharacter.IsMysticAdept)
                            {
                                await objWriter.WriteElementStringAsync("magadept", intMAGAdept.ToString(GlobalSettings.InvariantCultureInfo));
                            }
                        }

                        if (_objCharacter.RESEnabled)
                        {
                            await objWriter.WriteElementStringAsync("res", intRES.ToString(GlobalSettings.InvariantCultureInfo));
                        }
                        if (_objCharacter.DEPEnabled)
                        {
                            await objWriter.WriteElementStringAsync("dep", intDEP.ToString(GlobalSettings.InvariantCultureInfo));
                        }
                        // </attributes>
                        await objWriter.WriteEndElementAsync();
                    }

                    // Export Qualities.
                    if (await chkQualities.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        bool blnPositive = false;
                        bool blnNegative = false;
                        // Determine if Positive or Negative Qualities exist.
                        foreach (Quality objQuality in _objCharacter.Qualities)
                        {
                            switch (objQuality.Type)
                            {
                            case QualityType.Positive:
                                blnPositive = true;
                                break;

                            case QualityType.Negative:
                                blnNegative = true;
                                break;
                            }

                            if (blnPositive && blnNegative)
                            {
                                break;
                            }
                        }

                        // <qualities>
                        await objWriter.WriteStartElementAsync("qualities");

                        // Positive Qualities.
                        if (blnPositive)
                        {
                            // <positive>
                            await objWriter.WriteStartElementAsync("positive");

                            foreach (Quality objQuality in _objCharacter.Qualities)
                            {
                                if (objQuality.Type == QualityType.Positive)
                                {
                                    await objWriter.WriteStartElementAsync("quality");

                                    if (!string.IsNullOrEmpty(objQuality.Extra))
                                    {
                                        await objWriter.WriteAttributeStringAsync("select", objQuality.Extra);
                                    }
                                    objWriter.WriteValue(objQuality.Name);
                                    await objWriter.WriteEndElementAsync();
                                }
                            }

                            // </positive>
                            await objWriter.WriteEndElementAsync();
                        }

                        // Negative Qualities.
                        if (blnPositive)
                        {
                            // <negative>
                            await objWriter.WriteStartElementAsync("negative");

                            foreach (Quality objQuality in _objCharacter.Qualities)
                            {
                                if (objQuality.Type == QualityType.Negative)
                                {
                                    await objWriter.WriteStartElementAsync("quality");

                                    if (!string.IsNullOrEmpty(objQuality.Extra))
                                    {
                                        await objWriter.WriteAttributeStringAsync("select", objQuality.Extra);
                                    }
                                    objWriter.WriteValue(objQuality.Name);
                                    await objWriter.WriteEndElementAsync();
                                }
                            }

                            // </negative>
                            await objWriter.WriteEndElementAsync();
                        }

                        // </qualities>
                        await objWriter.WriteEndElementAsync();
                    }

                    // Export Starting Nuyen.
                    if (await chkStartingNuyen.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        decimal decNuyenBP = _objCharacter.NuyenBP;
                        if (!_objCharacter.EffectiveBuildMethodUsesPriorityTables)
                        {
                            decNuyenBP /= 2.0m;
                        }
                        await objWriter.WriteElementStringAsync("nuyenbp", decNuyenBP.ToString(GlobalSettings.InvariantCultureInfo));
                    }

                    /* TODO: Add support for active and knowledge skills and skill groups
                     * // Export Active Skills.
                     * if (await chkActiveSkills.DoThreadSafeFuncAsync(x => x.Checked))
                     * {
                     *  // <skills>
                     *  await objWriter.WriteStartElementAsync("skills");
                     *
                     *  // Active Skills.
                     *  foreach (Skill objSkill in _objCharacter.SkillsSection.Skills)
                     *  {
                     *      if (!objSkill.IsKnowledgeSkill && objSkill.Rating > 0)
                     *      {
                     *          // <skill>
                     *          await objWriter.WriteStartElementAsync("skill");
                     *          await objWriter.WriteElementStringAsync("name", objSkill.Name);
                     *          await objWriter.WriteElementStringAsync("rating", objSkill.Rating.ToString());
                     *          if (!string.IsNullOrEmpty(objSkill.Specialization))
                     *              await objWriter.WriteElementStringAsync("spec", objSkill.Specialization);
                     *          // </skill>
                     *          await objWriter.WriteEndElementAsync();
                     *      }
                     *  }
                     *
                     *  // Skill Groups.
                     *  foreach (SkillGroup objSkillGroup in _objCharacter.SkillsSection.SkillGroups)
                     *  {
                     *      if (objSkillGroup.BaseUnbroken && objSkillGroup.Rating > 0)
                     *      {
                     *          // <skillgroup>
                     *          await objWriter.WriteStartElementAsync("skillgroup");
                     *          await objWriter.WriteElementStringAsync("name", objSkillGroup.Name);
                     *          await objWriter.WriteElementStringAsync("rating", objSkillGroup.Rating.ToString());
                     *          // </skillgroup>
                     *          await objWriter.WriteEndElementAsync();
                     *      }
                     *  }
                     *  // </skills>
                     *  await objWriter.WriteEndElementAsync();
                     * }
                     *
                     * // Export Knowledge Skills.
                     * if (await chkKnowledgeSkills.DoThreadSafeFuncAsync(x => x.Checked))
                     * {
                     *  // <knowledgeskills>
                     *  await objWriter.WriteStartElementAsync("knowledgeskills");
                     *  foreach (KnowledgeSkill objSkill in _objCharacter.SkillsSection.Skills.OfType<KnowledgeSkill>())
                     *  {
                     *      // <skill>
                     *      await objWriter.WriteStartElementAsync("skill");
                     *      await objWriter.WriteElementStringAsync("name", objSkill.Name);
                     *      await objWriter.WriteElementStringAsync("rating", objSkill.Rating.ToString(GlobalSettings.InvariantCultureInfo));
                     *      if (!string.IsNullOrEmpty(objSkill.Specialization))
                     *          await objWriter.WriteElementStringAsync("spec", objSkill.Specialization);
                     *      await objWriter.WriteElementStringAsync("category", objSkill.SkillCategory);
                     *      // </skill>
                     *      await objWriter.WriteEndElementAsync();
                     *  }
                     *
                     *  // </knowledgeskills>
                     *  await objWriter.WriteEndElementAsync();
                     * }
                     */

                    // Export Martial Arts.
                    if (await chkMartialArts.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        // <martialarts>
                        await objWriter.WriteStartElementAsync("martialarts");

                        foreach (MartialArt objArt in _objCharacter.MartialArts)
                        {
                            // <martialart>
                            await objWriter.WriteStartElementAsync("martialart");

                            await objWriter.WriteElementStringAsync("name", objArt.Name);

                            if (objArt.Techniques.Count > 0)
                            {
                                // <techniques>
                                await objWriter.WriteStartElementAsync("techniques");

                                foreach (MartialArtTechnique objTechnique in objArt.Techniques)
                                {
                                    await objWriter.WriteElementStringAsync("technique", objTechnique.Name);
                                }
                                // </techniques>
                                await objWriter.WriteEndElementAsync();
                            }

                            // </martialart>
                            await objWriter.WriteEndElementAsync();
                        }
                        // </martialarts>
                        await objWriter.WriteEndElementAsync();
                    }

                    // Export Spells.
                    if (await chkSpells.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        // <spells>
                        await objWriter.WriteStartElementAsync("spells");

                        foreach (Spell objSpell in _objCharacter.Spells)
                        {
                            await objWriter.WriteStartElementAsync("spell");

                            await objWriter.WriteStartElementAsync("name");

                            if (!string.IsNullOrEmpty(objSpell.Extra))
                            {
                                await objWriter.WriteAttributeStringAsync("select", objSpell.Extra);
                            }
                            objWriter.WriteValue(objSpell.Name);
                            await objWriter.WriteEndElementAsync();

                            await objWriter.WriteElementStringAsync("category", objSpell.Category);

                            await objWriter.WriteEndElementAsync();
                        }

                        // </spells>
                        await objWriter.WriteEndElementAsync();
                    }

                    // Export Complex Forms.
                    if (await chkComplexForms.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        // <programs>
                        await objWriter.WriteStartElementAsync("complexforms");

                        foreach (ComplexForm objComplexForm in _objCharacter.ComplexForms)
                        {
                            // <program>
                            await objWriter.WriteStartElementAsync("complexform");

                            await objWriter.WriteStartElementAsync("name");

                            if (!string.IsNullOrEmpty(objComplexForm.Extra))
                            {
                                await objWriter.WriteAttributeStringAsync("select", objComplexForm.Extra);
                            }
                            objWriter.WriteValue(objComplexForm.Name);
                            await objWriter.WriteEndElementAsync();

                            await objWriter.WriteEndElementAsync();

                            // </program>
                            await objWriter.WriteEndElementAsync();
                        }

                        // </programs>
                        await objWriter.WriteEndElementAsync();
                    }

                    // Export Cyberware/Bioware.
                    if (await chkCyberware.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        bool blnCyberware = false;
                        bool blnBioware   = false;
                        foreach (Cyberware objCharacterCyberware in _objCharacter.Cyberware)
                        {
                            switch (objCharacterCyberware.SourceType)
                            {
                            case Improvement.ImprovementSource.Bioware:
                                blnBioware = true;
                                break;

                            case Improvement.ImprovementSource.Cyberware:
                                blnCyberware = true;
                                break;
                            }

                            if (blnCyberware && blnBioware)
                            {
                                break;
                            }
                        }

                        if (blnCyberware)
                        {
                            // <cyberwares>
                            await objWriter.WriteStartElementAsync("cyberwares");

                            foreach (Cyberware objCyberware in _objCharacter.Cyberware)
                            {
                                if (objCyberware.SourceType == Improvement.ImprovementSource.Cyberware)
                                {
                                    // <cyberware>
                                    await objWriter.WriteStartElementAsync("cyberware");

                                    await objWriter.WriteElementStringAsync("name", objCyberware.Name);

                                    if (objCyberware.Rating > 0)
                                    {
                                        await objWriter.WriteElementStringAsync("rating", objCyberware.Rating.ToString(GlobalSettings.InvariantCultureInfo));
                                    }
                                    await objWriter.WriteElementStringAsync("grade", objCyberware.Grade.Name);

                                    if (objCyberware.Children.Count > 0)
                                    {
                                        // <cyberwares>
                                        await objWriter.WriteStartElementAsync("cyberwares");

                                        foreach (Cyberware objChildCyberware in objCyberware.Children)
                                        {
                                            if (objChildCyberware.Capacity != "[*]")
                                            {
                                                // <cyberware>
                                                await objWriter.WriteStartElementAsync("cyberware");

                                                await objWriter.WriteElementStringAsync("name", objChildCyberware.Name);

                                                if (objChildCyberware.Rating > 0)
                                                {
                                                    await objWriter.WriteElementStringAsync("rating", objChildCyberware.Rating.ToString(GlobalSettings.InvariantCultureInfo));
                                                }

                                                if (objChildCyberware.GearChildren.Count > 0)
                                                {
                                                    await WriteGear(objWriter, objChildCyberware.GearChildren);
                                                }
                                                // </cyberware>
                                                await objWriter.WriteEndElementAsync();
                                            }
                                        }

                                        // </cyberwares>
                                        await objWriter.WriteEndElementAsync();
                                    }

                                    if (objCyberware.GearChildren.Count > 0)
                                    {
                                        await WriteGear(objWriter, objCyberware.GearChildren);
                                    }

                                    // </cyberware>
                                    await objWriter.WriteEndElementAsync();
                                }
                            }

                            // </cyberwares>
                            await objWriter.WriteEndElementAsync();
                        }

                        if (blnBioware)
                        {
                            // <biowares>
                            await objWriter.WriteStartElementAsync("biowares");

                            foreach (Cyberware objCyberware in _objCharacter.Cyberware)
                            {
                                if (objCyberware.SourceType == Improvement.ImprovementSource.Bioware)
                                {
                                    // <bioware>
                                    await objWriter.WriteStartElementAsync("bioware");

                                    await objWriter.WriteElementStringAsync("name", objCyberware.Name);

                                    if (objCyberware.Rating > 0)
                                    {
                                        await objWriter.WriteElementStringAsync("rating", objCyberware.Rating.ToString(GlobalSettings.InvariantCultureInfo));
                                    }
                                    await objWriter.WriteElementStringAsync("grade", objCyberware.Grade.ToString());

                                    if (objCyberware.GearChildren.Count > 0)
                                    {
                                        await WriteGear(objWriter, objCyberware.GearChildren);
                                    }
                                    // </bioware>
                                    await objWriter.WriteEndElementAsync();
                                }
                            }

                            // </biowares>
                            await objWriter.WriteEndElementAsync();
                        }
                    }

                    // Export Lifestyle.
                    if (await chkLifestyle.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        // <lifestyles>
                        await objWriter.WriteStartElementAsync("lifestyles");

                        foreach (Lifestyle objLifestyle in _objCharacter.Lifestyles)
                        {
                            // <lifestyle>
                            await objWriter.WriteStartElementAsync("lifestyle");

                            await objWriter.WriteElementStringAsync("name", objLifestyle.Name);

                            await objWriter.WriteElementStringAsync("months", objLifestyle.Increments.ToString(GlobalSettings.InvariantCultureInfo));

                            if (!string.IsNullOrEmpty(objLifestyle.BaseLifestyle))
                            {
                                // This is an Advanced Lifestyle, so write out its properties.
                                await objWriter.WriteElementStringAsync("cost", objLifestyle.Cost.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo));

                                await objWriter.WriteElementStringAsync("dice", objLifestyle.Dice.ToString(GlobalSettings.InvariantCultureInfo));

                                await objWriter.WriteElementStringAsync("multiplier", objLifestyle.Multiplier.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo));

                                await objWriter.WriteElementStringAsync("baselifestyle", objLifestyle.BaseLifestyle);

                                if (objLifestyle.LifestyleQualities.Count > 0)
                                {
                                    // <qualities>
                                    await objWriter.WriteStartElementAsync("qualities");

                                    foreach (LifestyleQuality objQuality in objLifestyle.LifestyleQualities)
                                    {
                                        await objWriter.WriteElementStringAsync("quality", objQuality.Name);
                                    }
                                    // </qualities>
                                    await objWriter.WriteEndElementAsync();
                                }
                            }

                            // </lifestyle>
                            await objWriter.WriteEndElementAsync();
                        }

                        // </lifestyles>
                        await objWriter.WriteEndElementAsync();
                    }

                    // Export Armor.
                    if (await chkArmor.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        // <armors>
                        await objWriter.WriteStartElementAsync("armors");

                        foreach (Armor objArmor in _objCharacter.Armor)
                        {
                            // <armor>
                            await objWriter.WriteStartElementAsync("armor");

                            await objWriter.WriteElementStringAsync("name", objArmor.Name);

                            if (objArmor.ArmorMods.Count > 0)
                            {
                                // <mods>
                                await objWriter.WriteStartElementAsync("mods");

                                foreach (ArmorMod objMod in objArmor.ArmorMods)
                                {
                                    // <mod>
                                    await objWriter.WriteStartElementAsync("mod");

                                    await objWriter.WriteElementStringAsync("name", objMod.Name);

                                    if (objMod.Rating > 0)
                                    {
                                        await objWriter.WriteElementStringAsync("rating", objMod.Rating.ToString(GlobalSettings.InvariantCultureInfo));
                                    }
                                    // </mod>
                                    await objWriter.WriteEndElementAsync();
                                }

                                // </mods>
                                await objWriter.WriteEndElementAsync();
                            }

                            if (objArmor.GearChildren.Count > 0)
                            {
                                await WriteGear(objWriter, objArmor.GearChildren);
                            }

                            // </armor>
                            await objWriter.WriteEndElementAsync();
                        }

                        // </armors>
                        await objWriter.WriteEndElementAsync();
                    }

                    // Export Weapons.
                    if (await chkWeapons.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        // <weapons>
                        await objWriter.WriteStartElementAsync("weapons");

                        foreach (Weapon objWeapon in _objCharacter.Weapons)
                        {
                            // Don't attempt to export Cyberware and Gear Weapons since those are handled by those object types. The default Unarmed Attack Weapon should also not be exported.
                            if (objWeapon.Category != "Cyberware" && objWeapon.Category != "Gear" && objWeapon.Name != "Unarmed Attack")
                            {
                                // <weapon>
                                await objWriter.WriteStartElementAsync("weapon");

                                await objWriter.WriteElementStringAsync("name", objWeapon.Name);

                                // Weapon Accessories.
                                if (objWeapon.WeaponAccessories.Count > 0)
                                {
                                    // <accessories>
                                    await objWriter.WriteStartElementAsync("accessories");

                                    foreach (WeaponAccessory objAccessory in objWeapon.WeaponAccessories)
                                    {
                                        // Don't attempt to export items included in the Weapon.
                                        if (!objAccessory.IncludedInWeapon)
                                        {
                                            // <accessory>
                                            await objWriter.WriteStartElementAsync("accessory");

                                            await objWriter.WriteElementStringAsync("name", objAccessory.Name);

                                            await objWriter.WriteElementStringAsync("mount", objAccessory.Mount);

                                            await objWriter.WriteElementStringAsync("extramount", objAccessory.ExtraMount);

                                            if (objAccessory.GearChildren.Count > 0)
                                            {
                                                await WriteGear(objWriter, objAccessory.GearChildren);
                                            }

                                            // </accessory>
                                            await objWriter.WriteEndElementAsync();
                                        }
                                    }

                                    // </accessories>
                                    await objWriter.WriteEndElementAsync();
                                }

                                // Underbarrel Weapon.
                                if (objWeapon.UnderbarrelWeapons.Count > 0)
                                {
                                    foreach (Weapon objUnderbarrelWeapon in objWeapon.UnderbarrelWeapons)
                                    {
                                        if (!objUnderbarrelWeapon.IncludedInWeapon)
                                        {
                                            await objWriter.WriteElementStringAsync("underbarrel", objUnderbarrelWeapon.Name);
                                        }
                                    }
                                }

                                // </weapon>
                                await objWriter.WriteEndElementAsync();
                            }
                        }

                        // </weapons>
                        await objWriter.WriteEndElementAsync();
                    }

                    // Export Gear.
                    if (await chkGear.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        await WriteGear(objWriter, _objCharacter.Gear);
                    }

                    // Export Vehicles.
                    if (await chkVehicles.DoThreadSafeFuncAsync(x => x.Checked))
                    {
                        // <vehicles>
                        await objWriter.WriteStartElementAsync("vehicles");

                        foreach (Vehicle objVehicle in _objCharacter.Vehicles)
                        {
                            bool blnWeapons = false;
                            // <vehicle>
                            await objWriter.WriteStartElementAsync("vehicle");

                            await objWriter.WriteElementStringAsync("name", objVehicle.Name);

                            if (objVehicle.Mods.Count > 0)
                            {
                                // <mods>
                                await objWriter.WriteStartElementAsync("mods");

                                foreach (VehicleMod objVehicleMod in objVehicle.Mods)
                                {
                                    // Only write out the Mods that are not part of the base vehicle.
                                    if (!objVehicleMod.IncludedInVehicle)
                                    {
                                        // <mod>
                                        await objWriter.WriteStartElementAsync("mod");

                                        await objWriter.WriteElementStringAsync("name", objVehicleMod.Name);

                                        if (objVehicleMod.Rating > 0)
                                        {
                                            await objWriter.WriteElementStringAsync("rating", objVehicleMod.Rating.ToString(GlobalSettings.InvariantCultureInfo));
                                        }
                                        // </mod>
                                        await objWriter.WriteEndElementAsync();

                                        // See if this is a Weapon Mount with Weapons.
                                        if (objVehicleMod.Weapons.Count > 0)
                                        {
                                            blnWeapons = true;
                                        }
                                    }
                                    else
                                    {
                                        // See if this is a Weapon Mount with Weapons.
                                        if (objVehicleMod.Weapons.Count > 0)
                                        {
                                            blnWeapons = true;
                                        }
                                    }
                                }

                                // </mods>
                                await objWriter.WriteEndElementAsync();
                            }

                            // If there are Weapons, add them.
                            if (blnWeapons)
                            {
                                // <weapons>
                                await objWriter.WriteStartElementAsync("weapons");

                                foreach (VehicleMod objVehicleMod in objVehicle.Mods)
                                {
                                    foreach (Weapon objWeapon in objVehicleMod.Weapons)
                                    {
                                        // <weapon>
                                        await objWriter.WriteStartElementAsync("weapon");

                                        await objWriter.WriteElementStringAsync("name", objWeapon.Name);

                                        // Weapon Accessories.
                                        if (objWeapon.WeaponAccessories.Count > 0)
                                        {
                                            // <accessories>
                                            await objWriter.WriteStartElementAsync("accessories");

                                            foreach (WeaponAccessory objAccessory in objWeapon.WeaponAccessories)
                                            {
                                                // Don't attempt to export items included in the Weapon.
                                                if (!objAccessory.IncludedInWeapon)
                                                {
                                                    // <accessory>
                                                    await objWriter.WriteStartElementAsync("accessory");

                                                    await objWriter.WriteElementStringAsync("name", objAccessory.Name);

                                                    await objWriter.WriteElementStringAsync("mount", objAccessory.Mount);

                                                    await objWriter.WriteElementStringAsync("extramount", objAccessory.ExtraMount);

                                                    // </accessory>
                                                    await objWriter.WriteEndElementAsync();
                                                }
                                            }

                                            // </accessories>
                                            await objWriter.WriteEndElementAsync();
                                        }

                                        // Underbarrel Weapon.
                                        if (objWeapon.UnderbarrelWeapons.Count > 0)
                                        {
                                            foreach (Weapon objUnderbarrelWeapon in objWeapon.UnderbarrelWeapons)
                                            {
                                                await objWriter.WriteElementStringAsync("underbarrel", objUnderbarrelWeapon.Name);
                                            }
                                        }

                                        // </weapon>
                                        await objWriter.WriteEndElementAsync();
                                    }
                                }

                                // </weapons>
                                await objWriter.WriteEndElementAsync();
                            }

                            // Gear.
                            if (objVehicle.GearChildren.Count > 0)
                            {
                                await WriteGear(objWriter, objVehicle.GearChildren);
                            }

                            // </vehicle>
                            await objWriter.WriteEndElementAsync();
                        }

                        // </vehicles>
                        await objWriter.WriteEndElementAsync();
                    }

                    // </pack>
                    await objWriter.WriteEndElementAsync();

                    // </packs>
                    await objWriter.WriteEndElementAsync();

                    // </chummer>
                    await objWriter.WriteEndElementAsync();

                    await objWriter.WriteEndDocumentAsync();
                }
            }

            Program.ShowMessageBox(this, string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Message_CreatePACKSKit_SuiteCreated"), strName),
                                   await LanguageManager.GetStringAsync("MessageTitle_CreatePACKSKit_SuiteCreated"), MessageBoxButtons.OK, MessageBoxIcon.Information);
            await this.DoThreadSafeAsync(x =>
            {
                x.DialogResult = DialogResult.OK;
                x.Close();
            });
        }
Esempio n. 7
0
        private static void LoadCharacterSettings()
        {
            _intDicLoadedCharacterSettingsLoadedStatus = 0;
            try
            {
                s_DicLoadedCharacterSettings.Clear();
                try
                {
                    if (Utils.IsDesignerMode || Utils.IsRunningInVisualStudio)
                    {
                        CharacterSettings objNewCharacterSettings = new CharacterSettings();
                        if (!s_DicLoadedCharacterSettings.TryAdd(GlobalSettings.DefaultCharacterSetting,
                                                                 objNewCharacterSettings))
                        {
                            objNewCharacterSettings.Dispose();
                        }
                        return;
                    }

                    Utils.RunWithoutThreadLock(async() =>
                    {
                        IEnumerable <XPathNavigator> xmlSettingsIterator
                            = (await(await XmlManager.LoadXPathAsync("settings.xml"))
                               .SelectAndCacheExpressionAsync("/chummer/settings/setting")).Cast <XPathNavigator>();
                        Parallel.ForEach(xmlSettingsIterator, xmlBuiltInSetting =>
                        {
                            CharacterSettings objNewCharacterSettings = new CharacterSettings();
                            if (!objNewCharacterSettings.Load(xmlBuiltInSetting) ||
                                (objNewCharacterSettings.BuildMethodIsLifeModule &&
                                 !GlobalSettings.LifeModuleEnabled) ||
                                !s_DicLoadedCharacterSettings.TryAdd(objNewCharacterSettings.DictionaryKey,
                                                                     objNewCharacterSettings))
                            {
                                objNewCharacterSettings.Dispose();
                            }
                        });
                    });
                }
                finally
                {
                    Interlocked.Increment(ref _intDicLoadedCharacterSettingsLoadedStatus);
                }

                Utils.RunWithoutThreadLock(() =>
                {
                    string strSettingsPath = Path.Combine(Utils.GetStartupPath, "settings");
                    if (Directory.Exists(strSettingsPath))
                    {
                        Parallel.ForEach(Directory.EnumerateFiles(strSettingsPath, "*.xml"), strSettingsFilePath =>
                        {
                            string strSettingName = Path.GetFileName(strSettingsFilePath);
                            CharacterSettings objNewCharacterSettings = new CharacterSettings();
                            if (!objNewCharacterSettings.Load(strSettingName, false) ||
                                (objNewCharacterSettings.BuildMethodIsLifeModule &&
                                 !GlobalSettings.LifeModuleEnabled) ||
                                !s_DicLoadedCharacterSettings.TryAdd(objNewCharacterSettings.DictionaryKey,
                                                                     objNewCharacterSettings))
                            {
                                objNewCharacterSettings.Dispose();
                            }
                        });
                    }
                });
            }
            finally
            {
                Interlocked.Increment(ref _intDicLoadedCharacterSettingsLoadedStatus);
            }
        }