/// <summary> /// Deserialization constructor. /// </summary> /// <param name="character">The character for this training</param> /// <param name="serial">The serialization object for this training</param> /// <param name="isPaused">When true, the training is currently paused.</param> /// <param name="startTimeWhenPaused">Training starttime when the queue is actually paused. /// Indeed, in such case, CCP returns empty start and end time, so we compute a "what if we start now" scenario.</param> internal QueuedSkill(Character character, SerializableQueuedSkill serial, bool isPaused, ref DateTime startTimeWhenPaused) { Owner = character; StartSP = serial.StartSP; EndSP = serial.EndSP; Level = serial.Level; Skill = character.Skills[serial.ID]; if (!isPaused) { // Not paused, we should trust CCP StartTime = serial.StartTime; EndTime = serial.EndTime; } else { // StartTime and EndTime were empty on the serialization object if the skill was paused // So we compute a "what if we start now" scenario StartTime = startTimeWhenPaused; if (Skill != null) { Skill.SkillPoints = StartSP; startTimeWhenPaused += Skill.GetLeftTrainingTimeForLevelOnly(Level); } EndTime = startTimeWhenPaused; } }
/// <summary> /// Constructor. /// </summary> /// <param name="character">The character</param> /// <param name="src">The static certificate class</param> /// <param name="category">The owning category</param> internal CertificateClass(Character character, StaticCertificateClass src, CertificateGroup category) { Character = character; Category = category; StaticData = src; Certificate = new Certificate(character, src.Certificate, this); }
/// <summary> /// Creation for new settings for this character. /// </summary> /// <param name="character">The character.</param> /// <exception cref="System.ArgumentNullException">character</exception> public MonitoredCharacterSettings(Character character) { character.ThrowIfNull(nameof(character)); CharacterGuid = character.Guid; Name = character.Name; Settings = character.UISettings; }
internal static Uri GetCharacterUri(Character character) { character.ThrowIfNull(nameof(character)); EveMonClient.EnsureCacheDirInit(); return new Uri(Path.Combine(EveMonClient.EVEMonXmlCacheDir, $"{character.Name}.xml")); }
/// <summary> /// Initializes a new instance of the <see cref="MasteryCertificate"/> class. /// </summary> /// <param name="character">The character.</param> /// <param name="masteryCertificate">The mastery certificate.</param> internal MasteryCertificate(Character character, MasteryCertificate masteryCertificate) { if (masteryCertificate == null) return; MasteryLevel = masteryCertificate.MasteryLevel; Certificate = masteryCertificate.ToCharacter(character); }
/// <summary> /// Constructor from the API. /// </summary> /// <param name="character"></param> /// <param name="src"></param> internal Standing(Character character, SerializableStandingsListItem src) { m_character = character; m_entityID = src.ID; EntityName = src.Name; StandingValue = src.StandingValue; Group = src.Group; }
/// <summary> /// Constructor from the settings. /// </summary> /// <param name="character">The character.</param> /// <param name="src">The source.</param> /// <exception cref="System.ArgumentNullException">src</exception> public EmploymentRecord(Character character, SerializableEmploymentHistory src) { src.ThrowIfNull(nameof(src)); m_character = character; m_corporationId = src.CorporationID; m_corporationName = src.CorporationName; StartDate = src.StartDate; }
/// <summary> /// Gets the character XML. /// </summary> /// <param name="character">The character.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException"></exception> public static IXPathNavigable GetCharacterXml(Character character) { character.ThrowIfNull(nameof(character)); EveMonClient.EnsureCacheDirInit(); XmlDocument doc = new XmlDocument(); doc.Load(Path.Combine(EveMonClient.EVEMonXmlCacheDir, $"{character.Name}.xml")); return doc; }
/// <summary> /// Constructor used in code. /// </summary> /// <param name="character"></param> /// <exception cref="System.ArgumentNullException">character</exception> public ImplantSetsWindow(Character character) : this() { character.ThrowIfNull(nameof(character)); m_character = character; m_sets = character.ImplantSets.Export(); m_maxJumpClones = character.Skills[DBConstants.InfomorphPsychologySkillID].Level + character.Skills[DBConstants.AdvancedInfomorphPsychologySkillID].Level; }
/// <summary> /// Initializes a new instance of the <see cref="CertificateLevel"/> class. /// </summary> /// <param name="skill">The skill.</param> /// <param name="cert">The cert.</param> /// <param name="character">The character.</param> public CertificateLevel(KeyValuePair<CertificateGrade, List<StaticSkillLevel>> skill, Certificate cert, Character character) { m_character = character; Level = skill.Key; Certificate = cert; Status = CertificateStatus.Untrained; PrerequisiteSkills = skill.Value.ToCharacter(character); }
/// <summary> /// Constructor /// </summary> /// <param name="plan">The plan.</param> private PlanPrinter(Plan plan) { m_plan = plan; m_plan.UpdateStatistics(); m_character = (Character)plan.Character; m_settings = Settings.Exportation.PlanToText; m_font = FontFactory.GetFont("Arial", 10); m_boldFont = FontFactory.GetFont("Arial", 10, FontStyle.Bold | FontStyle.Underline); }
/// <summary> /// Constructor from the API. /// </summary> /// <param name="character">The character.</param> /// <param name="src">The source.</param> /// <exception cref="System.ArgumentNullException">src</exception> public EmploymentRecord(Character character, SerializableEmploymentHistoryListItem src) { src.ThrowIfNull(nameof(src)); m_character = character; m_corporationId = src.CorporationID; m_corporationName = String.IsNullOrWhiteSpace(src.CorporationName) ? GetIDToName(src.CorporationID) : src.CorporationName; StartDate = src.StartDate; }
/// <summary> /// Constructor at character's initialization time. /// </summary> /// <param name="character"></param> /// <param name="src"></param> /// <param name="certClass"></param> internal Certificate(Character character, StaticCertificate src, CertificateClass certClass) { m_character = character; m_levels = new CertificateLevel[6]; StaticData = src; Class = certClass; foreach (KeyValuePair<CertificateGrade, List<StaticSkillLevel>> skill in src.PrerequisiteSkills) { m_levels[(int)skill.Key] = new CertificateLevel(skill, this, character); } }
/// <summary> /// Constructor from the API. /// </summary> /// <param name="character">The character.</param> /// <param name="src">The source.</param> internal KillLog(Character character, SerializableKillLogListItem src) { Character = character; KillTime = src.KillTime; TimeSinceKill = DateTime.UtcNow.Subtract(src.KillTime); MoonID = src.MoonID; Victim = src.Victim; Attackers = src.Attackers; SolarSystem = StaticGeography.GetSolarSystemByID(src.SolarSystemID); m_items.AddRange(src.Items.Select(item => new KillLogItem(item))); Group = src.Victim.ID == character.CharacterID ? KillGroup.Losses : KillGroup.Kills; }
/// <summary> /// Initializes a new instance of <see cref="AttributesOptimizerControl"/>. /// </summary> /// <param name="character">Character information</param> /// <param name="plan">Skill plan</param> /// <param name="remapping">Optimized remapping</param> /// <param name="description"></param> public AttributesOptimizerControl(Character character, BasePlan plan, RemappingResult remapping, string description) { InitializeComponent(); lbMEM.Font = FontFactory.GetFont("Tahoma"); lbWIL.Font = FontFactory.GetFont("Tahoma"); lbCHA.Font = FontFactory.GetFont("Tahoma"); lbPER.Font = FontFactory.GetFont("Tahoma"); lbINT.Font = FontFactory.GetFont("Tahoma"); m_character = character; m_plan = plan; m_remapping = remapping; m_description = description; UpdateControls(m_character, m_plan, m_remapping, m_description); }
/// <summary> /// Creates formatted string for character exportation. /// </summary> /// <param name="format"></param> /// <param name="character"></param> /// <param name="plan"></param> /// <exception cref="NotImplementedException"></exception> /// <returns></returns> public static string Export(CharacterSaveFormat format, Character character, Plan plan = null) { switch (format) { case CharacterSaveFormat.Text: return ExportAsText(character, plan); case CharacterSaveFormat.EFTCHR: return ExportAsEFTCHR(character, plan); case CharacterSaveFormat.EVEMonXML: return ExportAsEVEMonXML(character, plan); case CharacterSaveFormat.HTML: return ExportAsHTML(character, plan); case CharacterSaveFormat.CCPXML: return ExportAsCCPXML(character); default: throw new NotImplementedException(); } }
/// <summary> /// Creates a plan from a character skill queue. /// </summary> /// <param name="newPlan">The new plan.</param> /// <param name="character">The character.</param> public static bool CreatePlanFromCharacterSkillQueue(Plan newPlan, Character character) { CCPCharacter ccpCharacter = character as CCPCharacter; if (ccpCharacter == null) return false; if (!ccpCharacter.SkillQueue.Any()) { MessageBox.Show(@"There are no skills in the characters' queue.", @"Plan Creation Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return false; } if (ccpCharacter.Plans.Any(x => x.Name == newPlan.Name)) { MessageBox.Show(@"There is already a plan with the same name in the characters' Plans.", @"Plan Creation Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return false; } // Add skill queue in plan foreach (QueuedSkill qSkill in ccpCharacter.SkillQueue) { newPlan.PlanTo(qSkill.Skill, qSkill.Level); } // Check if there is already a plan with the same skills if (ccpCharacter.Plans.Any(plan => !newPlan.Except(plan, new PlanEntryComparer()).Any())) { MessageBox.Show(@"There is already a plan with the same skills in the characters' Plans.", @"Plan Creation Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return false; } // Add plan and save ccpCharacter.Plans.Insert(0, newPlan); return true; }
/// <summary> /// Constructor. /// </summary> /// <param name="character">The character.</param> /// <param name="queuedSkills">The queued skills.</param> public QueuedSkillsEventArgs(Character character, IEnumerable<QueuedSkill> queuedSkills) { Character = character; CompletedSkills = new List<QueuedSkill>(queuedSkills).AsReadOnly(); }
/// <summary> /// Sends a mail alert for a skill completion /// </summary> /// <param name="queueList">Current Skill Queue</param> /// <param name="skill">Skill that has just completed</param> /// <param name="character">Character affected</param> /// <exception cref="System.ArgumentNullException"> /// </exception> public static void SendSkillCompletionMail(IList<QueuedSkill> queueList, QueuedSkill skill, Character character) { s_isTestMail = false; queueList.ThrowIfNull(nameof(queueList)); skill.ThrowIfNull(nameof(skill)); CCPCharacter ccpCharacter = character as CCPCharacter; // Current character isn't a CCP character, so can't have a Queue. if (ccpCharacter == null) return; string skillLevelText = $"{skill.SkillName} {Skill.GetRomanFromInt(skill.Level)}"; string subjectText = $"{character.Name} has finished training {skillLevelText}."; // Message's first line StringBuilder body = new StringBuilder(); body .AppendLine(subjectText) .AppendLine(); // Next skills in queue if (queueList[0] != null) { string plural = queueList.Count > 1 ? "s" : String.Empty; body.AppendLine($"Next skill{plural} in queue:"); foreach (QueuedSkill qskill in queueList) { body.AppendLine($"- {qskill}"); } body.AppendLine(); } else body .AppendLine("Character is not training.") .AppendLine(); // Skill queue less than a day if (ccpCharacter.SkillQueue.LessThanWarningThreshold) { TimeSpan skillQueueEndTime = ccpCharacter.SkillQueue.EndTime.Subtract(DateTime.UtcNow); TimeSpan timeLeft = SkillQueue.WarningThresholdTimeSpan.Subtract(skillQueueEndTime); // Skill queue empty? if (timeLeft > SkillQueue.WarningThresholdTimeSpan) body.AppendLine("Skill queue is empty."); else { string timeLeftText = skillQueueEndTime < TimeSpan.FromMinutes(1) ? skillQueueEndTime.ToDescriptiveText(DescriptiveTextOptions.IncludeCommas) : skillQueueEndTime.ToDescriptiveText(DescriptiveTextOptions.IncludeCommas, false); body.AppendLine($"Queue ends in {timeLeftText}."); } } // Short format (also for SMS) if (Settings.Notifications.UseEmailShortFormat) { SendMail(Settings.Notifications, $"[STC] {character.Name} :: {skillLevelText}", body.ToString()); return; } // Long format if (character.Plans.Count > 0) { body.AppendLine("Next skills listed in plans:") .AppendLine(); } foreach (Plan plan in character.Plans) { if (plan.Count <= 0) continue; // Print plan name CharacterScratchpad scratchpad = new CharacterScratchpad(character); body.AppendLine($"{plan.Name}:"); // Scroll through entries int i = 0; int minDays = 1; foreach (PlanEntry entry in plan) { TimeSpan trainTime = scratchpad.GetTrainingTime(entry.Skill, entry.Level, TrainingOrigin.FromPreviousLevelOrCurrent); // Only print the first three skills, and the very long skills // (first limit is one day, then we add skills duration) if (++i > 3 && trainTime.Days <= minDays) continue; if (i > 3) { // Print long message once if (minDays == 1) body.AppendLine().Append($"Longer skills from {plan.Name}:").AppendLine(); minDays = trainTime.Days + minDays; } body.Append($"\t{entry}"); // Notes if (!string.IsNullOrEmpty(entry.Notes)) body.Append($" ({entry.Notes})"); // Training time body .Append(trainTime.Days > 0 ? $" - {trainTime.Days}d, {trainTime}" : $" - {trainTime}") .AppendLine(); } body.AppendLine(); } SendMail(Settings.Notifications, subjectText, body.ToString()); }
/// <summary> /// Outputs a plan or shopping list for a given character to a stream writer. /// </summary> /// <param name="context">context of the request</param> /// <param name="requestPath">url of the request</param> /// <param name="sw">stream writer to output to</param> /// <param name="character">character to use</param> private static void GeneratePlanOrShoppingOutput(string context, string requestPath, TextWriter sw, Character character) { sw.WriteLine("<h1>Hello, {0}</h1>", HttpUtility.HtmlEncode(character.Name)); sw.WriteLine("<a href=\"/characters\">List all characters</a><hr/>"); sw.WriteLine("<a href=\"{0}\">Character overview</a>", context); Regex regex = new Regex( @"\/(owned\/(?'skillId'[^\/]+)\/(?'markOwned'[^\/]+)\/)?(?'requestType'shopping|plan)\/(?'planName'[^\/]+)(.*)", RegexOptions.CultureInvariant | RegexOptions.Compiled); Match match = regex.Match(requestPath); if (match.Success) { string requestType = match.Groups["requestType"].Value; bool shopping = requestType.Equals("shopping", StringComparison.OrdinalIgnoreCase); string planName = HttpUtility.UrlDecode(match.Groups["planName"].Value); int skillId; bool setAsOwned; if (match.Groups["skillId"].Success && match.Groups["markOwned"].Success && Int32.TryParse(match.Groups["skillId"].Value, out skillId) && Boolean.TryParse(match.Groups["markOwned"].Value, out setAsOwned)) { Skill skill = character.Skills.FirstOrDefault(x => x.ID == skillId); if (skill != null) { sw.WriteLine("<h2>Skillbook shopping result</h2>"); skill.IsOwned = setAsOwned; sw.WriteLine("<a href=\"\" onclick=\"CCPEVE.showInfo({0})\">{1}</a> is now marked as {2} owned.", skill.ID, HttpUtility.HtmlEncode(skill.Name), skill.IsOwned ? String.Empty : "not"); } else { // Display an error message sw.WriteLine("<h2>Error Message</h2>"); sw.WriteLine("Skill with id '{0}' could not be found", skillId); } sw.WriteLine("<hr/>"); } Plan plan = character.Plans[planName]; if (plan == null) { // Display an error message sw.WriteLine("<h2>Error Message</h2>"); sw.WriteLine("A plan named \"{0}\" does not exist.", HttpUtility.HtmlEncode(planName)); } else { sw.WriteLine("<h2>Plan: {0}</h2>", HttpUtility.HtmlEncode(plan.Name)); PlanExportSettings x = new PlanExportSettings { // Only if not shopping EntryTrainingTimes = !shopping, // Only if not shopping EntryStartDate = !shopping, // Only if not shopping EntryFinishDate = !shopping, // Only if not shopping FooterTotalTime = !shopping, // Only if not shopping FooterDate = !shopping, FooterCount = true, ShoppingList = shopping, EntryCost = true, FooterCost = true, Markup = MarkupType.Html }; sw.Write(PlanIOHelper.ExportAsText(plan, x, ExportActions(context, requestType, plan))); } } else { sw.WriteLine("<h2>Error Message</h2>"); sw.WriteLine("Invalid request"); } sw.WriteLine("<br/><br/><a href=\"{0}\">Character overview</a>", context); sw.WriteLine("<hr/><a href=\"/characters\">List all characters</a>"); }
/// <summary> /// Outputs a list of skills for a given character ordered by time to a stream writer. /// </summary> /// <param name="context">context of the request</param> /// <param name="sw">stream writer to output to</param> /// <param name="character">character to use</param> private static void GenerateSkillsByTimeOutput(string context, TextWriter sw, Character character) { sw.WriteLine("<h1>Hello, {0}</h1>", HttpUtility.HtmlEncode(character.Name)); sw.WriteLine("<a href=\"/characters\">List all characters</a><hr/>"); sw.WriteLine("<a href=\"{0}\">Character overview</a>", context); sw.WriteLine("<h2>Your skills by training time:</h2>"); IEnumerable<Skill> allskills = character.Skills.Where(x => x.IsPublic && x.Level < 5 && x.Level > 0); allskills = allskills.OrderBy(x => x.GetLeftTrainingTimeToNextLevel); sw.WriteLine("<table>"); sw.Write("<tr><td colspan=\"2\" width=\"265\"><b>Skill</b></td>" + "<td width=\"100\"><b>Next Level</b></td><td><b>Training Time</b></td></tr>"); int index = 0; foreach (Skill s in allskills) { index++; sw.Write("<tr>"); sw.Write("<td width=\"15\">"); sw.Write("<b>{0}.</b>", index); sw.Write("</td>"); sw.Write("<td width=\"300\">"); sw.Write("<b><a href=\"\" onclick=\"CCPEVE.showInfo({0})\">{1}</a></b>", s.ID, s.Name); sw.Write("</td>"); sw.Write("<td width=\"100\">"); sw.Write("<b>{0} -> {1}</b>", s.RomanLevel, Skill.GetRomanFromInt(s.Level + 1)); sw.Write("</td>"); sw.Write("<td>"); sw.Write(s.GetLeftTrainingTimeToNextLevel.ToDescriptiveText( DescriptiveTextOptions.FullText | DescriptiveTextOptions.IncludeCommas | DescriptiveTextOptions.SpaceText)); sw.Write("</td>"); sw.Write("</tr>"); } sw.WriteLine("</table>"); sw.WriteLine("<br/><a href=\"{0}\">Character overview</a>", context); sw.WriteLine("<hr/><a href=\"/characters\">List all characters</a>"); }
/// <summary> /// Outputs a list of plans for a given character to a stream writer. /// </summary> /// <param name="context">context of the request</param> /// <param name="sw">stream writer to output to</param> /// <param name="character">character to use</param> private static void GeneratePlanListOutput(string context, TextWriter sw, Character character) { sw.WriteLine("<h1>Hello, {0}</h1>", HttpUtility.HtmlEncode(character.Name)); sw.WriteLine("<a href=\"/characters\">List all characters</a><hr/>"); sw.WriteLine("<h2>Your plans:</h2>"); foreach (Plan plan in character.Plans) { sw.WriteLine("<a href=\"{0}/plan/{1}\">{2}</a> (<a href=\"{0}/shopping/{1}\">shopping list</a>)<br/>", context, HttpUtility.UrlEncode(plan.Name), HttpUtility.HtmlEncode(plan.Name)); } sw.WriteLine("<h2>Your skills:</h2>"); sw.WriteLine("<a href=\"{0}/skills/bytime\">By training time</a><br/>", context); sw.WriteLine("<hr/><a href=\"/characters\">List all characters</a>"); }
/// <summary> /// Constructor. /// </summary> /// <param name="character">The character.</param> /// <param name="industryJobs">The industry jobs.</param> public IndustryJobsEventArgs(Character character, IEnumerable<IndustryJob> industryJobs) { Character = character; CompletedJobs = industryJobs.ToList().AsReadOnly(); }
/// <summary> /// Returns an equivalent enumeration with character skills. /// </summary> /// <param name="src"></param> /// <param name="character"></param> /// <returns></returns> public static IEnumerable<SkillLevel> ToCharacter(this IEnumerable<StaticSkillLevel> src, Character character) => src.Where(item => item.Skill != null) .Select(item => new SkillLevel(character?.Skills[item.Skill.ID] ?? SkillCollection.Skills[item.Skill.ID], item.Level));
/// <summary> /// Internal constructor, only used for character creation and updates /// </summary> /// <param name="owner"></param> /// <param name="group"></param> /// <param name="skill"></param> internal Skill(Character owner, SkillGroup group, StaticSkill skill) { Character = owner; StaticData = skill; Group = group; }
/// <summary> /// Gets this skill's representation for the provided character. /// </summary> /// <param name="character"></param> /// <returns></returns> public Skill ToCharacter(Character character) { character.ThrowIfNull(nameof(character)); return character.Skills[StaticData.ArrayIndex]; }
/// <summary> /// Constructor. /// </summary> /// <param name="character"></param> public CharacterChangedEventArgs(Character character) { Character = character; }
/// <summary> /// Gets this certificate's representation for the provided character. /// </summary> /// <returns></returns> /// <exception cref="System.ArgumentNullException">character</exception> public Certificate ToCharacter(Character character) { character.ThrowIfNull(nameof(character)); return character.Certificates.FirstOrDefault(x => x.ID == Certificate.ID); }
/// <summary> /// Constructor. /// </summary> /// <param name="character">The character.</param> /// <param name="endedContracts">The ended contracts.</param> public ContractsEventArgs(Character character, IEnumerable<Contract> endedContracts) { Character = character; EndedContracts = endedContracts; }
/// <summary> /// Returns an equivalent enumeration with character skills. /// </summary> /// <param name="src"></param> /// <param name="character"></param> /// <returns></returns> public static IEnumerable<Skill> ToCharacter(this IEnumerable<StaticSkill> src, Character character) => src.Select(skill => character.Skills[skill.ID]);