Example #1
0
        /// <summary>
        /// Imports data from the given skills information.
        /// </summary>
        /// <param name="skills">The serialized character skill information</param>
        internal void Import(EsiAPISkills skills, EsiAPISkillQueue queue)
        {
            var      newSkills   = new LinkedList <SerializableCharacterSkill>();
            DateTime uselessDate = DateTime.UtcNow;

            FreeSkillPoints = skills.UnallocatedSP;

            // Keep track of the current skill queue's completed skills, as ESI does not
            // transfer them to the skills list until you login
            var dict = new Dictionary <long, SerializableQueuedSkill>();

            if (queue != null)
            {
                foreach (var queuedSkill in queue.CreateSkillQueue())
                {
                    // If the skill is completed or currently training, we need it later to
                    // copy the progress over to the imported skills
                    if (queuedSkill.IsCompleted || queuedSkill.IsTraining)
                    {
                        if (!dict.ContainsKey(queuedSkill.ID))
                        {
                            dict.Add(queuedSkill.ID, queuedSkill);
                        }
                        else
                        {
                            dict[queuedSkill.ID] = queuedSkill;
                        }
                    }
                }
            }
            // Convert skills to EVE format
            foreach (var skill in skills.Skills)
            {
                // Check if the skill is in the queue, and completed at a higher level or has
                // higher current SP
                if (dict.ContainsKey(skill.ID))
                {
                    var queuedSkill = dict[skill.ID];
                    if (queuedSkill.IsCompleted)
                    {
                        // Queued skill is completed, so make sure the imported skill is
                        // updated
                        skill.ActiveLevel = Math.Max(skill.ActiveLevel, queuedSkill.Level);
                        skill.Level       = Math.Max(skill.Level, queuedSkill.Level);
                        skill.Skillpoints = Math.Max(skill.Skillpoints, queuedSkill.EndSP);
                    }
                    else if (queuedSkill.IsTraining)
                    {
                        // Queued skill is currently training - use QueuedSkill class to
                        // calculate the CurrentSP of the skill
                        var tempSkill = new QueuedSkill(this, queuedSkill, ref uselessDate);
                        skill.Skillpoints = Math.Max(skill.Skillpoints, tempSkill.CurrentSP);
                    }
                }
                newSkills.AddLast(skill.ToXMLItem());
            }
            Skills.Import(newSkills, true);

            UpdateMasteries();
        }
Example #2
0
        /// <summary>
        /// Imports data from the given skills information.
        /// </summary>
        /// <param name="skills">The serialized character skill information</param>
        internal void Import(EsiAPISkills skills, EsiAPISkillQueue queue)
        {
            var newSkills = new LinkedList <SerializableCharacterSkill>();

            FreeSkillPoints = skills.UnallocatedSP;

            // Keep track of the current skill queue's completed skills, as ESI doesn't transfer them to the skills list until you login
            Dictionary <long, QueuedSkill> dict = new Dictionary <long, QueuedSkill>();

            if (queue != null && IsTraining)
            {
                DateTime uselessDate = DateTime.UtcNow;

                foreach (var serialSkill in queue.ToXMLItem().Queue)
                {
                    var queuedSkill = new QueuedSkill(this, serialSkill, ref uselessDate);
                    if (!dict.ContainsKey(queuedSkill.Skill.ID))
                    {
                        dict.Add(queuedSkill.Skill.ID, queuedSkill);
                    }
                    else if (queuedSkill.Level > dict[queuedSkill.Skill.ID].Level)
                    {
                        dict[queuedSkill.Skill.ID] = queuedSkill;
                    }
                }
            }
            // Convert skills to EVE format
            foreach (var skill in skills.Skills)
            {
                // Check if the skill is in the queue, and completed at a higher level or has higher current SP
                if (dict.ContainsKey(skill.ID))
                {
                    var queuedSkill = dict[skill.ID];

                    if (queuedSkill.IsCompleted)
                    {
                        skill.ActiveLevel = Math.Max(skill.ActiveLevel, queuedSkill.Level);
                        skill.Level       = Math.Max(skill.Level, queuedSkill.Level);
                        skill.Skillpoints = Math.Max(skill.Skillpoints, queuedSkill.EndSP);
                    }
                    else
                    {
                        skill.Skillpoints = Math.Max(skill.Skillpoints, queuedSkill.CurrentSP);
                    }
                }

                newSkills.AddLast(skill.ToXMLItem());
            }

            Skills.Import(newSkills, true);
        }
Example #3
0
 /// <summary>
 /// Updates the skill to match the one from the queue
 /// </summary>
 internal void UpdateSkillProgress(QueuedSkill queuedSkill)
 {
     m_known = true;
     if (queuedSkill.IsCompleted)
     {
         m_level     = Math.Min(queuedSkill.Level, s_maxLevel);
         SkillPoints = queuedSkill.EndSP;
     }
     else
     {
         m_level     = queuedSkill.Level - 1;
         SkillPoints = queuedSkill.CurrentSP;
     }
 }
Example #4
0
        /// <summary>
        /// Process the queue into MS Outlook.
        /// </summary>
        /// <param name="queuedSkill">The queued skill.</param>
        /// <param name="queuePosition">The queue position.</param>
        /// <param name="lastSkillInQueue">if set to <c>true</c> skill is the last in queue.</param>
        private static async Task DoOutlookAppointmentAsync(QueuedSkill queuedSkill, int queuePosition, bool lastSkillInQueue)
        {
            // Get the calendar
            if (!OutlookCalendarEvent.OutlookCalendarExist(Settings.Calendar.UseOutlookDefaultCalendar))
            {
                MessageBox.Show(@"Outlook calendar does not exist. Please check your settings.", @"Outlook Error",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Set the subject to the character name and the skill and level in queue for uniqueness sake
            OutlookCalendarEvent outlookAppointmentFilter = new OutlookCalendarEvent
            {
                StartDate = DateTime.Now.AddDays(-40),
                EndDate = DateTime.Now.AddDays(100),
                Subject = String.Format(
                    CultureConstants.DefaultCulture,
                    "{0} - {1} {2}",
                    queuedSkill.Owner.Name,
                    queuedSkill.SkillName,
                    Skill.GetRomanFromInt(queuedSkill.Level))
            };


            // Pull the list of appointments, hopefully we should either get 1 or none back
            await outlookAppointmentFilter.ReadEventsAsync();

            // If there is an appointment, get the first one
            bool foundAppointment = false;
            if (outlookAppointmentFilter.ItemCount > 0)
                foundAppointment = outlookAppointmentFilter.GetEvent();

            // Update the appointment we may have pulled or the new one
            // Set the appointment length to 5 minutes, starting at the estimated completion date and time
            // Reminder value was already validated
            // Use the values from the screen as these may differ what the user has set for defaults
            outlookAppointmentFilter.StartDate = queuedSkill.EndTime.ToLocalTime();
            outlookAppointmentFilter.EndDate = queuedSkill.EndTime.ToLocalTime().AddMinutes(5);
            outlookAppointmentFilter.ItemReminder = Settings.Calendar.UseReminding;
            outlookAppointmentFilter.AlternateReminder = Settings.Calendar.UseAlternateReminding;
            outlookAppointmentFilter.EarlyReminder = Settings.Calendar.EarlyReminding;
            outlookAppointmentFilter.LateReminder = Settings.Calendar.LateReminding;
            outlookAppointmentFilter.Minutes = Settings.Calendar.RemindingInterval;

            await outlookAppointmentFilter.AddOrUpdateEventAsync(foundAppointment, queuePosition, lastSkillInQueue);
        }
Example #5
0
        /// <summary>
        /// Process the queue into Google calendar.
        /// </summary>
        /// <param name="queuedSkill">The queued skill.</param>
        /// <param name="queuePosition">The queue position.</param>
        /// <param name="lastSkillInQueue">if set to <c>true</c> skill is the last in queue.</param>
        private static async Task DoGoogleAppointmentAsync(QueuedSkill queuedSkill, int queuePosition, bool lastSkillInQueue)
        {
            try
            {
                // Set the subject to the character name and the skill and level in queue for uniqueness sakes
                GoogleCalendarEvent googleAppointmentFilter = new GoogleCalendarEvent
                {
                    StartDate = DateTime.Now.AddDays(-40),
                    EndDate = DateTime.Now.AddDays(100),
                    Subject = String.Format(
                        CultureConstants.DefaultCulture,
                        "{0} - {1} {2}",
                        queuedSkill.Owner.Name,
                        queuedSkill.SkillName,
                        Skill.GetRomanFromInt(queuedSkill.Level))
                };

                // Pull the list of appointments, hopefully we should either get 1 or none back
                await googleAppointmentFilter.ReadEventsAsync();

                // If there is are appointments, see if any match the subject
                bool foundAppointment = false;
                if (googleAppointmentFilter.ItemCount > 0)
                    foundAppointment = googleAppointmentFilter.GetEvent();

                // Update the appointment we may have pulled or the new one
                // Set the appointment length to 5 minutes, starting at the estimated completion date and time
                // Reminder interval was already validated
                // Use the values from the screen as these may differ what the user has set for defaults
                googleAppointmentFilter.StartDate = queuedSkill.EndTime.ToLocalTime();
                googleAppointmentFilter.EndDate = queuedSkill.EndTime.ToLocalTime().AddMinutes(5);
                googleAppointmentFilter.ItemReminder = Settings.Calendar.UseReminding;
                googleAppointmentFilter.AlternateReminder = Settings.Calendar.UseAlternateReminding;
                googleAppointmentFilter.EarlyReminder = Settings.Calendar.EarlyReminding;
                googleAppointmentFilter.LateReminder = Settings.Calendar.LateReminding;
                googleAppointmentFilter.Minutes = Settings.Calendar.RemindingInterval;
                googleAppointmentFilter.ReminderMethod = Settings.Calendar.GoogleEventReminder;

                await googleAppointmentFilter.AddOrUpdateEventAsync(foundAppointment, queuePosition, lastSkillInQueue);
            }
            catch (TokenResponseException ex)
            {
                MessageBox.Show(ex.Error.ErrorDescription, @"Google Calendar");
            }
            catch (GoogleApiException ex)
            {
                MessageBox.Show(ex.Error.Message, @"Google Calendar");
            }
            catch (APIException ex)
            {
                MessageBox.Show(ex.Message, ex.ErrorCode ?? @"Google Calendar");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, @"Google Calendar");
            }
        }
Example #6
0
 /// <summary>
 /// Check if the input level is higher than the current level
 /// </summary>
 /// <param name="newLevel"></param>
 /// <returns></returns>
 internal bool HasBeenCompleted(QueuedSkill queuedSkill)
 {
     return(Math.Min(queuedSkill.Level, s_maxLevel) > m_level);
 }
Example #7
0
        /// <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());
        }
Example #8
0
 /// <summary>
 /// Displays the skill tool tip.
 /// </summary>
 /// <param name="skillRect">The skill rect.</param>
 /// <param name="skill">The skill.</param>
 private void DisplaySkillToolTip(RectangleF skillRect, QueuedSkill skill)
 {
     const string Format = "{0} {1}\n  Start{2}\t{3}\n  Ends\t{4}";
     string skillName = skill.SkillName;
     string skillLevel = Skill.GetRomanFromInt(skill.Level);
     string skillStart = skill.Owner.IsTraining
         ? skill.StartTime.ToLocalTime().ToAbsoluteDateTimeDescription(DateTimeKind.Local)
         : "Paused";
     string skillEnd = skill.Owner.IsTraining
         ? skill.EndTime.ToLocalTime().ToAbsoluteDateTimeDescription(DateTimeKind.Local)
         : "Paused";
     string startText = skill.StartTime < DateTime.UtcNow ? "ed" : "s";
     string text = String.Format(CultureConstants.DefaultCulture, Format, skillName, skillLevel, startText, skillStart,
         skillEnd);
     Size textSize = TextRenderer.MeasureText(text, Font);
     Size toolTipSize = new Size(textSize.Width + 13, textSize.Height + 11);
     Point tipPoint = new Point((int)(Math.Min(skillRect.Right, Width) + skillRect.Left) / 2 - toolTipSize.Width / 2,
         -toolTipSize.Height);
     tipPoint.Offset(0, -21);
     m_toolTip.Show(text, tipPoint);
 }