internal void CallPlugins(frmCareer frmCareer, CustomActivity parentActivity) { foreach (var plugin in MyActivePlugins) { using (var op_plugin = Timekeeper.StartSyncron("load_plugin_GetTabPage_Career_" + plugin.ToString(), parentActivity, CustomActivity.OperationType.DependencyOperation, plugin.ToString())) { var pages = plugin.GetTabPages(frmCareer); if (pages == null) { continue; } foreach (TabPage page in pages) { if (page != null) { if (!frmCareer.TabCharacterTabs.TabPages.Contains(page)) { frmCareer.TabCharacterTabs.TabPages.Add(page); } } } } } }
internal void CallPlugins(ToolStripMenuItem menu, CustomActivity parentActivity) { foreach (var plugin in MyActivePlugins) { using (var op_plugin = Timekeeper.StartSyncron("load_plugin_GetMenuItems_" + plugin.ToString(), parentActivity, CustomActivity.OperationType.DependencyOperation, plugin.ToString())) { var menuitems = plugin.GetMenuItems(menu); if (menuitems == null) { continue; } foreach (ToolStripMenuItem plugInMenu in menuitems) { if (plugInMenu != null) { if (!menu.DropDownItems.Contains(plugInMenu)) { menu.DropDownItems.Add(plugInMenu); } } } } } }
internal void LoadPlugins(CustomActivity parentActivity = null) { try { using (_ = Timekeeper.StartSyncron("LoadPlugins", parentActivity, CustomActivity.OperationType.DependencyOperation, _objMyDirectoryCatalog?.FullPath)) Initialize(); } catch (System.Security.SecurityException e) { string msg = "Well, something went wrong probably because we are not Admins. Let's just ignore it and move on." + Environment.NewLine + Environment.NewLine; Log.Warn(e, msg); } catch (ReflectionTypeLoadException e) { using (new FetchSafelyFromPool <StringBuilder>(Utils.StringBuilderPool, out StringBuilder sbdMessage)) { sbdMessage.AppendLine("Exception loading plugins: "); foreach (Exception exp in e.LoaderExceptions) { sbdMessage.AppendLine(exp.Message); } sbdMessage.AppendLine(); sbdMessage.Append(e); Log.Warn(e, sbdMessage.ToString()); } } catch (CompositionException e) { using (new FetchSafelyFromPool <StringBuilder>(Utils.StringBuilderPool, out StringBuilder sbdMessage)) { sbdMessage.AppendLine("Exception loading plugins: "); foreach (CompositionError exp in e.Errors) { sbdMessage.AppendLine(exp.Exception.ToString()); } sbdMessage.AppendLine(); sbdMessage.Append(e); Log.Error(e, sbdMessage.ToString()); } } catch (ApplicationException) { throw; } catch (Exception e) { string msg = "Exception loading plugins: " + Environment.NewLine; msg += Environment.NewLine; msg += e.ToString(); Log.Error(e, msg); } }
internal void LoadPlugins(CustomActivity parentActivity) { try { using (var op_plugin = Timekeeper.StartSyncron("LoadPlugins", parentActivity, CustomActivity.OperationType.DependencyOperation, myDirectoryCatalog?.FullPath)) { this.Initialize(); } } catch (System.Security.SecurityException e) { string msg = "Well, something went wrong probably because we are not Admins. Let's just ignore it and move on." + Environment.NewLine + Environment.NewLine; Console.WriteLine(msg + e.Message); System.Diagnostics.Trace.TraceWarning(msg + e.Message); return; } catch (ReflectionTypeLoadException e) { string msg = "Exception loading plugins: " + Environment.NewLine; foreach (var exp in e.LoaderExceptions) { msg += exp.Message + Environment.NewLine; } msg += Environment.NewLine; msg += e.ToString(); Log.Warn(e, msg); } catch (CompositionException e) { string msg = "Exception loading plugins: " + Environment.NewLine; foreach (var exp in e.Errors) { msg += exp.Exception + Environment.NewLine; } msg += Environment.NewLine; msg += e.ToString(); Log.Error(e, msg); } catch (ApplicationException e) { throw; } catch (Exception e) { string msg = "Exception loading plugins: " + Environment.NewLine; msg += Environment.NewLine; msg += e.ToString(); Log.Error(e, msg); } }
internal void CallPlugins(CharacterCreate frmCreate, CustomActivity parentActivity) { foreach (IPlugin plugin in MyActivePlugins) { using (_ = Timekeeper.StartSyncron("load_plugin_GetTabPage_Create_" + plugin, parentActivity, CustomActivity.OperationType.DependencyOperation, plugin.ToString())) { IEnumerable <TabPage> pages = plugin.GetTabPages(frmCreate); if (pages == null) { continue; } foreach (TabPage page in pages) { if (page != null && !frmCreate.TabCharacterTabs.TabPages.Contains(page)) { frmCreate.TabCharacterTabs.TabPages.Add(page); } } } } }
private async Task <MyUserState> ShareChummerGroup() { try { string hash = ""; using (var op_shareChummer = Timekeeper.StartSyncron("Share Group", null, CustomActivity.OperationType.DependencyOperation, MySINnerSearchGroup?.Groupname)) { MyUserState myState = new MyUserState(this); var client = StaticUtils.GetClient(); if (string.IsNullOrEmpty(MySINnerSearchGroup?.Id?.ToString())) { myState.StatusText = "Group Id is unknown or not issued!"; ReportProgress(30, myState); } else { myState.StatusText = "Group Id is " + MySINnerSearchGroup?.Id + "."; myState.CurrentProgress = 30; ReportProgress(myState.CurrentProgress, myState); } //check if char is already online and updated using (var op_checkOnlineVersionChummer = Timekeeper.StartSyncron( "check if online", op_shareChummer, CustomActivity.OperationType.DependencyOperation, MySINnerSearchGroup?.Groupname)) { HttpOperationResponse <ResultGroupGetGroupById> checkresult = await client.GetGroupByIdWithHttpMessagesAsync(MySINnerSearchGroup?.Id).ConfigureAwait(false); if (checkresult == null) { throw new ArgumentException("Could not parse result from SINners Webservice!"); } if (checkresult.Response.StatusCode != HttpStatusCode.NotFound) { if (checkresult.Body.CallSuccess != true) { if (checkresult.Body.MyException is Exception myException) { throw new ArgumentException( "Error from SINners Webservice: " + checkresult.Body.ErrorText, myException); } throw new ArgumentException("Error from SINners Webservice: " + checkresult.Body.ErrorText); } hash = checkresult.Body.MyGroup.MyHash; } } myState.StatusText = "Group is online available."; myState.CurrentProgress = 90; ReportProgress(myState.CurrentProgress, myState); string url = client.BaseUri + "G"; url += "/" + hash; if (Properties.Settings.Default.OpenChummerFromSharedLinks == true) { url += "?open=true"; } myState.LinkText = url; ReportProgress(100, myState); RunWorkerCompleted(myState); return(myState); } } catch (Exception exception) { Log.Warn(exception); throw; } }
private async Task <MyUserState> ShareSingleChummer() { string hash = ""; try { using (var op_shareChummer = Timekeeper.StartSyncron("Share Chummer", null, CustomActivity.OperationType.DependencyOperation, MyCharacterCache?.FilePath)) { MyUserState myState = new MyUserState(this); CharacterExtended ce = null; var client = StaticUtils.GetClient(); string sinnerid = ""; Guid SINid = Guid.Empty; async Task <CharacterExtended> GetCharacterExtended(CustomActivity parentActivity) { using (var op_prepChummer = Timekeeper.StartSyncron("Loading Chummerfile", parentActivity, CustomActivity.OperationType.DependencyOperation, MyCharacterCache?.FilePath)) { Character c = new Character() { FileName = MyCharacterCache.FilePath }; var foundchar = (from a in PluginHandler.MainForm.OpenCharacters where a.FileName == MyCharacterCache.FilePath select a).ToList(); if (foundchar?.Any() == true) { c = foundchar?.FirstOrDefault(); } else { using (frmLoading frmLoadingForm = new frmLoading { CharacterFile = MyCharacterCache.FilePath }) { frmLoadingForm.Reset(36); frmLoadingForm.TopMost = true; frmLoadingForm.Show(); myState.StatusText = "Loading chummer file..."; myState.CurrentProgress += 10; ReportProgress(myState.CurrentProgress, myState); await c.Load(frmLoadingForm, false).ConfigureAwait(true); } } if (c == null) { throw new ArgumentNullException("Could not load Character file " + MyCharacterCache.FilePath + "."); } ce = new CharacterExtended(c, null, null, MyCharacterCache); if (ce?.MySINnerFile?.Id != null) { sinnerid = ce.MySINnerFile.Id.ToString(); } hash = ce?.MySINnerFile?.MyHash; return(ce); } } if (MyCharacterCache.MyPluginDataDic.TryGetValue("SINnerId", out Object sinneridobj)) { sinnerid = sinneridobj?.ToString(); } else { ce = await GetCharacterExtended(op_shareChummer).ConfigureAwait(true); sinnerid = ce.MySINnerFile.Id.ToString(); hash = ce?.MySINnerFile?.MyHash; } if (string.IsNullOrEmpty(sinnerid) || !Guid.TryParse(sinnerid, out SINid)) { myState.StatusText = "SINner Id is unknown or not issued!"; ReportProgress(30, myState); } else { myState.StatusText = "SINner Id is " + SINid + "."; myState.CurrentProgress = 30; ReportProgress(myState.CurrentProgress, myState); } HttpOperationResponse <ResultSinnerGetSINById> checkresult = null; //check if char is already online and updated using (var op_checkOnlineVersionChummer = Timekeeper.StartSyncron( "check if online", op_shareChummer, CustomActivity.OperationType.DependencyOperation, MyCharacterCache?.FilePath)) { checkresult = await client.GetSINByIdWithHttpMessagesAsync(SINid).ConfigureAwait(true); if (checkresult == null) { throw new ArgumentException("Could not parse result from SINners Webservice!"); } if (checkresult.Response.StatusCode != HttpStatusCode.NotFound) { if (checkresult.Body.CallSuccess != true) { if (checkresult.Body.MyException is Exception myException) { throw new ArgumentException( "Error from SINners Webservice: " + checkresult.Body.ErrorText, myException); } throw new ArgumentException("Error from SINners Webservice: " + checkresult.Body.ErrorText); } hash = checkresult.Body.MySINner.MyHash; } } var lastWriteTimeUtc = System.IO.File.GetLastWriteTimeUtc(MyCharacterCache.FilePath); if (checkresult.Response.StatusCode == HttpStatusCode.NotFound || checkresult.Body.MySINner.LastChange < lastWriteTimeUtc) { if (ce == null) { myState.StatusText = "The Chummer is newer and has to be uploaded again."; myState.CurrentProgress = 30; ReportProgress(myState.CurrentProgress, myState); ce = await GetCharacterExtended(op_shareChummer).ConfigureAwait(true); } using (var op_uploadChummer = Timekeeper.StartSyncron( "Uploading Chummer", op_shareChummer, CustomActivity.OperationType.DependencyOperation, MyCharacterCache?.FilePath)) { myState.StatusText = "Checking SINner availability (and if necessary upload it)."; myState.CurrentProgress = 35; ReportProgress(myState.CurrentProgress, myState); myState.ProgressSteps = 10; var uploadtask = await ce.Upload(myState, op_uploadChummer).ConfigureAwait(true); SINid = ce.MySINnerFile.Id.Value; var result = await client.GetSINByIdWithHttpMessagesAsync(SINid).ConfigureAwait(true); if (result == null) { throw new ArgumentException("Could not parse result from SINners Webservice!"); } if (result.Body?.CallSuccess != true) { if (result.Body?.MyException is Exception myException) { throw new ArgumentException( "Error from SINners Webservice: " + result.Body?.ErrorText, myException); } throw new ArgumentException( "Error from SINners Webservice: " + result.Body?.ErrorText); } hash = result.Body.MySINner.MyHash; } } myState.StatusText = "SINner is online available."; myState.CurrentProgress = 90; ReportProgress(myState.CurrentProgress, myState); string url = client.BaseUri + "O"; url += "/" + hash; if (Properties.Settings.Default.OpenChummerFromSharedLinks == true) { url += "?open=true"; } myState.LinkText = url; ReportProgress(100, myState); RunWorkerCompleted(myState); return(myState); } } catch (Exception exception) { Log.Warn(exception); throw; } }
public async Task <bool> Upload(ucSINnerShare.MyUserState myState = null, CustomActivity parentActivity = null) { using (var op_uploadChummer = Timekeeper.StartSyncron( "Uploading Chummer", parentActivity, CustomActivity.OperationType.DependencyOperation, MyCharacter?.FileName)) { try { using (new CursorWait(true, PluginHandler.MainForm)) { HttpOperationResponse <ResultSinnerGetSINById> found = null; using (var op_checkalreadyonlineChummer = Timekeeper.StartSyncron( "Checking if already online Chummer", op_uploadChummer, CustomActivity.OperationType.DependencyOperation, MyCharacter?.FileName)) { if (myState != null) { //1 Step myState.CurrentProgress += myState.ProgressSteps; myState.StatusText = "Checking online version of file..."; myState.myWorker?.ReportProgress(myState.CurrentProgress, myState); } if (MySINnerFile.DownloadedFromSINnersTime > this.MyCharacter.FileLastWriteTime) { if (myState != null) { myState.CurrentProgress += 4 * myState.ProgressSteps; myState.StatusText = "File already uploaded."; myState.myWorker?.ReportProgress(myState.CurrentProgress, myState); } return(true); } var client = StaticUtils.GetClient(); found = await client.GetSINByIdWithHttpMessagesAsync(this.MySINnerFile.Id.GetValueOrDefault()); await Backend.Utils.HandleError(found, found.Body); } if (myState != null) { //2 Step myState.CurrentProgress += myState.ProgressSteps; } using (var op_VisibilityChummer = Timekeeper.StartSyncron( "Setting Visibility for Chummer", op_uploadChummer, CustomActivity.OperationType.DependencyOperation, MyCharacter?.FileName)) { if (found.Response.StatusCode == System.Net.HttpStatusCode.OK) { if (found.Body.MySINner.LastChange >= this.MyCharacter.FileLastWriteTime) { if (myState != null) { myState.StatusText = "SINner already uploaded and updated online."; myState.CurrentProgress += 3 * myState.ProgressSteps; myState.myWorker?.ReportProgress(myState.CurrentProgress, myState); } return(true); } if (myState != null) { myState.StatusText = "SINner needs to be uploaded."; myState.myWorker?.ReportProgress(myState.CurrentProgress, myState); } if (!MySINnerFile.SiNnerMetaData.Visibility.UserRights.Any()) { MySINnerFile.SiNnerMetaData.Visibility.UserRights = found.Body.MySINner.SiNnerMetaData.Visibility.UserRights; } } } using (var op_PopulatingChummer = Timekeeper.StartSyncron( "Populating Reflection Tags", op_uploadChummer, CustomActivity.OperationType.DependencyOperation, MyCharacter?.FileName)) { this.MySINnerFile.SiNnerMetaData.Tags = this.PopulateTags(); } using (var op_PopulatingChummer = Timekeeper.StartSyncron( "Preparing Model", op_uploadChummer, CustomActivity.OperationType.DependencyOperation, MyCharacter?.FileName)) { await this.PrepareModel(); } if (myState != null) { //3 Step myState.CurrentProgress += myState.ProgressSteps; myState.StatusText = "Chummerfile prepared for uploading..."; myState.myWorker?.ReportProgress(myState.CurrentProgress, myState); } HttpOperationResponse <ResultSinnerPostSIN> res = null; using (var op_PopulatingChummer = Timekeeper.StartSyncron( "Posting SINner", op_uploadChummer, CustomActivity.OperationType.DependencyOperation, MyCharacter?.FileName)) { res = await ChummerHub.Client.Backend.Utils.PostSINnerAsync(this); await Backend.Utils.HandleError(res, res.Body); } if (myState != null) { //4 Step myState.CurrentProgress += myState.ProgressSteps; myState.StatusText = "Chummer Metadata stored in DB..."; myState.myWorker?.ReportProgress(myState.CurrentProgress, myState); } if (res.Response.IsSuccessStatusCode) { using (var op_PopulatingChummer = Timekeeper.StartSyncron( "Uploading File", op_uploadChummer, CustomActivity.OperationType.DependencyOperation, MyCharacter?.FileName)) { var uploadres = await ChummerHub.Client.Backend.Utils.UploadChummerFileAsync(this); if (uploadres.Response.IsSuccessStatusCode) { if (myState != null) { //5 Step myState.CurrentProgress += myState.ProgressSteps; myState.StatusText = "Chummer uploaded..."; myState.myWorker?.ReportProgress(myState.CurrentProgress, myState); } return(true); } if (myState != null) { //5 Step myState.CurrentProgress += myState.ProgressSteps; myState.StatusText = "Chummer upload failed: " + uploadres.Response.ReasonPhrase; myState.myWorker?.ReportProgress(myState.CurrentProgress, myState); } return(false); } } if (myState != null) { //5 Step myState.CurrentProgress += myState.ProgressSteps; myState.StatusText = "Chummer upload of Metadata failed: " + res.Response.ReasonPhrase; myState.myWorker?.ReportProgress(myState.CurrentProgress, myState); } return(false); } } catch (Exception e) { op_uploadChummer?.tc?.TrackException(e); await Backend.Utils.HandleError(e); throw; } } }
private async Task <MyUserState> ShareSingleChummer() { if (MyCharacterCache == null) { throw new ArgumentNullException(nameof(MyCharacterCache)); } string hash = string.Empty; try { using (CustomActivity op_shareChummer = Timekeeper.StartSyncron("Share Chummer", null, CustomActivity.OperationType.DependencyOperation, MyCharacterCache.FilePath)) { MyUserState myState = new MyUserState(this); CharacterExtended ce = null; SinnersClient client = StaticUtils.GetClient(); string sinnerid = string.Empty; Guid SINid = Guid.Empty; try { async Task <CharacterExtended> GetCharacterExtended(CustomActivity parentActivity) { using (_ = Timekeeper.StartSyncron("Loading Chummerfile", parentActivity, CustomActivity.OperationType.DependencyOperation, MyCharacterCache.FilePath)) { Character c = PluginHandler.MainForm.OpenCharacters.FirstOrDefault(a => a.FileName == MyCharacterCache.FilePath); bool blnSuccess = true; if (c == null) { c = new Character { FileName = MyCharacterCache.FilePath }; using (LoadingBar frmLoadingForm = new LoadingBar { CharacterFile = MyCharacterCache.FilePath }) { frmLoadingForm.Reset(36); frmLoadingForm.Show(); myState.StatusText = "Loading chummer file..."; myState.CurrentProgress += 10; ReportProgress(myState.CurrentProgress, myState); blnSuccess = await c.LoadAsync(frmLoadingForm, false); } } if (!blnSuccess) { throw new ArgumentNullException("Could not load Character file " + MyCharacterCache.FilePath + "."); } ce = new CharacterExtended(c, null, MyCharacterCache); if (ce?.MySINnerFile?.Id != null) { sinnerid = ce.MySINnerFile.Id.ToString(); } hash = ce?.MySINnerFile?.MyHash; return(ce); } } if (MyCharacterCache.MyPluginDataDic.TryGetValue("SINnerId", out object sinneridobj)) { sinnerid = sinneridobj?.ToString() ?? string.Empty; } else { ce = await GetCharacterExtended(op_shareChummer); sinnerid = ce.MySINnerFile.Id.ToString(); hash = ce?.MySINnerFile?.MyHash ?? string.Empty; } if (string.IsNullOrEmpty(sinnerid) || !Guid.TryParse(sinnerid, out SINid)) { myState.StatusText = "SINner Id is unknown or not issued!"; ReportProgress(30, myState); } else { myState.StatusText = "SINner Id is " + SINid + "."; myState.CurrentProgress = 30; ReportProgress(myState.CurrentProgress, myState); } try { //check if char is already online and updated ResultSinnerGetSINById checkresult; using (_ = Timekeeper.StartSyncron( "check if online", op_shareChummer, CustomActivity.OperationType.DependencyOperation, MyCharacterCache?.FilePath)) { checkresult = await client.GetSINByIdAsync(SINid); if (checkresult == null) { throw new ArgumentException("Could not parse result from SINners Webservice!"); } if (!checkresult.CallSuccess) { if (checkresult.MyException != null) { throw new ArgumentException( "Error from SINners Webservice: " + checkresult.ErrorText, checkresult.MyException.ToString()); } throw new ArgumentException("Error from SINners Webservice: " + checkresult.ErrorText); } hash = checkresult.MySINner.MyHash; } DateTime lastWriteTimeUtc = MyCharacterCache != null?File.GetLastWriteTimeUtc(MyCharacterCache.FilePath) : DateTime.MinValue; if (checkresult.MySINner.LastChange < lastWriteTimeUtc) { if (ce == null) { myState.StatusText = "The Chummer is newer and has to be uploaded again."; myState.CurrentProgress = 30; ReportProgress(myState.CurrentProgress, myState); ce = await GetCharacterExtended(op_shareChummer); } if (ce != null) { using (CustomActivity op_uploadChummer = Timekeeper.StartSyncron( "Uploading Chummer", op_shareChummer, CustomActivity.OperationType.DependencyOperation, MyCharacterCache?.FilePath)) { myState.StatusText = "Checking SINner availability (and if necessary upload it)."; myState.CurrentProgress = 35; ReportProgress(myState.CurrentProgress, myState); myState.ProgressSteps = 10; await ce.Upload(myState, op_uploadChummer); if (ce.MySINnerFile.Id != null) { SINid = ce.MySINnerFile.Id.Value; } ResultSinnerGetSINById result = await client.GetSINByIdAsync(SINid); if (result == null) { throw new ArgumentException( "Could not parse result from SINners Webservice!"); } if (!result.CallSuccess) { if (result.MyException != null) { throw new ArgumentException( "Error from SINners Webservice: " + result.ErrorText, result.MyException.ToString()); } throw new ArgumentException( "Error from SINners Webservice: " + result.ErrorText); } hash = result.MySINner.MyHash; } } } } finally { //checkresult?.Dispose(); } } finally { ce?.Dispose(); } myState.StatusText = "SINner is online available."; myState.CurrentProgress = 90; ReportProgress(myState.CurrentProgress, myState); string url = client.BaseUrl + "O"; url += "/" + hash; if (Settings.Default.OpenChummerFromSharedLinks) { url += "?open=true"; } myState.LinkText = url; ReportProgress(100, myState); RunWorkerCompleted(myState); return(myState); } } catch (Exception exception) { Log.Warn(exception); throw; } }
public async void LoadFromHeroLab(XmlNode xmlStatBlockBaseNode, CustomActivity parentActivity) { using (var op_load_char_attrib = Timekeeper.StartSyncron("load_char_attrib", parentActivity)) { foreach (CharacterAttrib objAttribute in AttributeList.Concat(SpecialAttributeList)) { objAttribute.UnbindAttribute(); } AttributeList.Clear(); SpecialAttributeList.Clear(); XmlDocument objXmlDocument = XmlManager.Load(_objCharacter.IsCritter ? "critters.xml" : "metatypes.xml"); XmlNode xmlMetatypeNode = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _objCharacter.Metatype + "\"]"); XmlNode xmlCharNode = xmlMetatypeNode?.SelectSingleNode("metavariants/metavariant[name = \"" + _objCharacter.Metavariant + "\"]") ?? xmlMetatypeNode; // We only want to remake attributes for shifters in career mode, because they only get their second set of attributes when exporting from create mode into career mode XmlNode xmlCharNodeAnimalForm = _objCharacter.MetatypeCategory == "Shapeshifter" && _objCharacter.Created ? xmlMetatypeNode : null; foreach (string strAttribute in AttributeStrings) { // First, remake the attribute CharacterAttrib objAttribute = null; switch (CharacterAttrib.ConvertToAttributeCategory(strAttribute)) { case CharacterAttrib.AttributeCategory.Special: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Special); objAttribute = RemakeAttribute(objAttribute, xmlCharNode); SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Standard: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Standard); objAttribute = RemakeAttribute(objAttribute, xmlCharNode); AttributeList.Add(objAttribute); break; } if (xmlCharNodeAnimalForm != null) { switch (CharacterAttrib.ConvertToAttributeCategory(strAttribute)) { case CharacterAttrib.AttributeCategory.Special: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Special); objAttribute = RemakeAttribute(objAttribute, xmlCharNodeAnimalForm); SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Shapeshifter: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Shapeshifter); objAttribute = RemakeAttribute(objAttribute, xmlCharNodeAnimalForm); AttributeList.Add(objAttribute); break; } } // Then load in attribute karma levels (we'll adjust these later if the character is in Create mode) if (strAttribute == "ESS" ) // Not Essence though, this will get modified automatically instead of having its value set to the one HeroLab displays { continue; } XmlNode xmlHeroLabAttributeNode = xmlStatBlockBaseNode.SelectSingleNode( "attributes/attribute[@name = \"" + GetAttributeEnglishName(strAttribute) + "\"]"); XmlNode xmlAttributeBaseNode = xmlHeroLabAttributeNode?.SelectSingleNode("@base"); if (xmlAttributeBaseNode != null && int.TryParse(xmlAttributeBaseNode.InnerText, out int intHeroLabAttributeBaseValue)) { int intAttributeMinimumValue = GetAttributeByName(strAttribute).MetatypeMinimum; if (intHeroLabAttributeBaseValue == intAttributeMinimumValue) { continue; } if (objAttribute != null) { objAttribute.Karma = intHeroLabAttributeBaseValue - intAttributeMinimumValue; } } } if (!_objCharacter.Created && _objCharacter.BuildMethodHasSkillPoints) { // Allocate Attribute Points int intAttributePointCount = _objCharacter.TotalAttributes; CharacterAttrib objAttributeToPutPointsInto; // First loop through attributes where costs can be 100% covered with points do { objAttributeToPutPointsInto = null; int intAttributeToPutPointsIntoTotalKarmaCost = 0; foreach (CharacterAttrib objLoopAttribute in AttributeList) { if (objLoopAttribute.Karma == 0) { continue; } // Put points into the attribute with the highest total karma cost. // In case of ties, pick the one that would need more points to cover it (the other one will hopefully get picked up at a later cycle) int intLoopTotalKarmaCost = objLoopAttribute.TotalKarmaCost; if (objAttributeToPutPointsInto == null || (objLoopAttribute.Karma <= intAttributePointCount && (intLoopTotalKarmaCost > intAttributeToPutPointsIntoTotalKarmaCost || (intLoopTotalKarmaCost == intAttributeToPutPointsIntoTotalKarmaCost && objLoopAttribute.Karma > objAttributeToPutPointsInto.Karma)))) { objAttributeToPutPointsInto = objLoopAttribute; intAttributeToPutPointsIntoTotalKarmaCost = intLoopTotalKarmaCost; } } if (objAttributeToPutPointsInto != null) { objAttributeToPutPointsInto.Base = objAttributeToPutPointsInto.Karma; intAttributePointCount -= objAttributeToPutPointsInto.Karma; objAttributeToPutPointsInto.Karma = 0; } } while (objAttributeToPutPointsInto != null && intAttributePointCount > 0); // If any points left over, then put them all into the attribute with the highest karma cost if (intAttributePointCount > 0 && AttributeList.Any(x => x.Karma != 0)) { int intHighestTotalKarmaCost = 0; foreach (CharacterAttrib objLoopAttribute in AttributeList) { if (objLoopAttribute.Karma == 0) { continue; } // Put points into the attribute with the highest total karma cost. // In case of ties, pick the one that would need more points to cover it (the other one will hopefully get picked up at a later cycle) int intLoopTotalKarmaCost = objLoopAttribute.TotalKarmaCost; if (objAttributeToPutPointsInto == null || intLoopTotalKarmaCost > intHighestTotalKarmaCost || (intLoopTotalKarmaCost == intHighestTotalKarmaCost && objLoopAttribute.Karma > objAttributeToPutPointsInto.Karma)) { objAttributeToPutPointsInto = objLoopAttribute; intHighestTotalKarmaCost = intLoopTotalKarmaCost; } } if (objAttributeToPutPointsInto != null) { objAttributeToPutPointsInto.Base = intAttributePointCount; objAttributeToPutPointsInto.Karma -= intAttributePointCount; } } // Allocate Special Attribute Points intAttributePointCount = _objCharacter.TotalSpecial; // First loop through attributes where costs can be 100% covered with points do { objAttributeToPutPointsInto = null; int intAttributeToPutPointsIntoTotalKarmaCost = 0; foreach (CharacterAttrib objLoopAttribute in SpecialAttributeList) { if (objLoopAttribute.Karma == 0) { continue; } // Put points into the attribute with the highest total karma cost. // In case of ties, pick the one that would need more points to cover it (the other one will hopefully get picked up at a later cycle) int intLoopTotalKarmaCost = objLoopAttribute.TotalKarmaCost; if (objAttributeToPutPointsInto == null || (objLoopAttribute.Karma <= intAttributePointCount && (intLoopTotalKarmaCost > intAttributeToPutPointsIntoTotalKarmaCost || (intLoopTotalKarmaCost == intAttributeToPutPointsIntoTotalKarmaCost && objLoopAttribute.Karma > objAttributeToPutPointsInto.Karma)))) { objAttributeToPutPointsInto = objLoopAttribute; intAttributeToPutPointsIntoTotalKarmaCost = intLoopTotalKarmaCost; } } if (objAttributeToPutPointsInto != null) { objAttributeToPutPointsInto.Base = objAttributeToPutPointsInto.Karma; intAttributePointCount -= objAttributeToPutPointsInto.Karma; objAttributeToPutPointsInto.Karma = 0; } } while (objAttributeToPutPointsInto != null); // If any points left over, then put them all into the attribute with the highest karma cost if (intAttributePointCount > 0 && SpecialAttributeList.Any(x => x.Karma != 0)) { int intHighestTotalKarmaCost = 0; foreach (CharacterAttrib objLoopAttribute in SpecialAttributeList) { if (objLoopAttribute.Karma == 0) { continue; } // Put points into the attribute with the highest total karma cost. // In case of ties, pick the one that would need more points to cover it (the other one will hopefully get picked up at a later cycle) int intLoopTotalKarmaCost = objLoopAttribute.TotalKarmaCost; if (objAttributeToPutPointsInto == null || intLoopTotalKarmaCost > intHighestTotalKarmaCost || (intLoopTotalKarmaCost == intHighestTotalKarmaCost && objLoopAttribute.Karma > objAttributeToPutPointsInto.Karma)) { objAttributeToPutPointsInto = objLoopAttribute; intHighestTotalKarmaCost = intLoopTotalKarmaCost; } } if (objAttributeToPutPointsInto != null) { objAttributeToPutPointsInto.Base = intAttributePointCount; objAttributeToPutPointsInto.Karma -= intAttributePointCount; } } } ResetBindings(); _objCharacter.RefreshAttributeBindings(); //Timekeeper.Finish("load_char_attrib"); } }
public async void Create(XmlNode charNode, int intValue, int intMinModifier = 0, int intMaxModifier = 0) { using (var op_create_char_attrib = Timekeeper.StartSyncron("create_char_attrib", null, CustomActivity.OperationType.RequestOperation, charNode?.InnerText)) { foreach (CharacterAttrib objAttribute in AttributeList.Concat(SpecialAttributeList)) { objAttribute.UnbindAttribute(); } AttributeList.Clear(); SpecialAttributeList.Clear(); foreach (string strAttribute in AttributeStrings) { CharacterAttrib objAttribute; switch (CharacterAttrib.ConvertToAttributeCategory(strAttribute)) { case CharacterAttrib.AttributeCategory.Special: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Special); SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Standard: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Standard); AttributeList.Add(objAttribute); break; } } _objCharacter.BOD.AssignLimits( CommonFunctions.ExpressionToString(charNode["bodmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["bodmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["bodaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.AGI.AssignLimits( CommonFunctions.ExpressionToString(charNode["agimin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["agimax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["agiaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.REA.AssignLimits( CommonFunctions.ExpressionToString(charNode["reamin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["reamax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["reaaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.STR.AssignLimits( CommonFunctions.ExpressionToString(charNode["strmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["strmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["straug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.CHA.AssignLimits( CommonFunctions.ExpressionToString(charNode["chamin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["chamax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["chaaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.INT.AssignLimits( CommonFunctions.ExpressionToString(charNode["intmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["intmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["intaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.LOG.AssignLimits( CommonFunctions.ExpressionToString(charNode["logmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["logmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["logaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.WIL.AssignLimits( CommonFunctions.ExpressionToString(charNode["wilmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["wilmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["wilaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.MAG.AssignLimits( CommonFunctions.ExpressionToString(charNode["magmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["magmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["magaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.RES.AssignLimits( CommonFunctions.ExpressionToString(charNode["resmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["resmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["resaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.EDG.AssignLimits( CommonFunctions.ExpressionToString(charNode["edgmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["edgmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["edgaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.DEP.AssignLimits( CommonFunctions.ExpressionToString(charNode["depmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["depmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["depaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.MAGAdept.AssignLimits( CommonFunctions.ExpressionToString(charNode["magmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["magmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["magaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.ESS.AssignLimits( CommonFunctions.ExpressionToString(charNode["essmin"]?.InnerText, intValue, 0), CommonFunctions.ExpressionToString(charNode["essmax"]?.InnerText, intValue, 0), CommonFunctions.ExpressionToString(charNode["essaug"]?.InnerText, intValue, 0)); Attributes = new ObservableCollection <CharacterAttrib> { _objCharacter.BOD, _objCharacter.AGI, _objCharacter.REA, _objCharacter.STR, _objCharacter.CHA, _objCharacter.INT, _objCharacter.LOG, _objCharacter.WIL, _objCharacter.EDG }; if (_objCharacter.MAGEnabled) { Attributes.Add(_objCharacter.MAG); if (_objCharacter.Options.MysAdeptSecondMAGAttribute && _objCharacter.IsMysticAdept) { Attributes.Add(_objCharacter.MAGAdept); } } if (_objCharacter.RESEnabled) { Attributes.Add(_objCharacter.RES); } if (_objCharacter.DEPEnabled) { Attributes.Add(_objCharacter.DEP); } ResetBindings(); _objCharacter.RefreshAttributeBindings(); //Timekeeper.Finish("create_char_attrib"); } }