예제 #1
0
        private DialogResult WarnAboutResetting()
        {
            var warnUser = false;

            for (var index = 0; index < fzzy.state.Run.Count; index++)
            {
                if (!LiveSplitStateHelper.CheckBestSegment(fzzy.state, index, fzzy.state.CurrentTimingMethod))
                {
                    continue;
                }
                warnUser = true;
                break;
            }

            if (!warnUser && (fzzy.state.Run.Last().SplitTime[fzzy.state.CurrentTimingMethod] != null &&
                              fzzy.state.Run.Last().PersonalBestSplitTime[fzzy.state.CurrentTimingMethod] == null) ||
                fzzy.state.Run.Last().SplitTime[fzzy.state.CurrentTimingMethod] <
                fzzy.state.Run.Last().PersonalBestSplitTime[fzzy.state.CurrentTimingMethod])
            {
                warnUser = true;
            }
            if (!warnUser)
            {
                return(DialogResult.Yes);
            }
            var result = MessageBox.Show("You have beaten some of your best times.\r\nDo you want to update them?",
                                         "Update Times?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

            return(result);
        }
예제 #2
0
 private void CheckLiveSegmentDelta(LiveSplitState state, string comparison)
 {
     IsLiveDeltaActive = false;
     if (Settings.IsLiveGraph)
     {
         if (state.CurrentPhase == TimerPhase.Running || state.CurrentPhase == TimerPhase.Paused)
         {
             var bestSeg  = LiveSplitStateHelper.CheckLiveDelta(state, true, comparison, state.CurrentTimingMethod);
             var curSplit = state.Run[state.CurrentSplitIndex].Comparisons[comparison][state.CurrentTimingMethod];
             var curTime  = state.CurrentTime[state.CurrentTimingMethod];
             if (bestSeg == null && curSplit != null && curTime - curSplit > MinDelta)
             {
                 bestSeg = curTime - curSplit;
             }
             if (bestSeg != null)
             {
                 if (bestSeg > MaxDelta)
                 {
                     MaxDelta = bestSeg.Value;
                 }
                 if (bestSeg < MinDelta)
                 {
                     MinDelta = bestSeg.Value;
                 }
                 Deltas.Add(bestSeg);
                 IsLiveDeltaActive = true;
             }
         }
     }
 }
        private bool isGoldSplit()
        {
            int      splitIndex = state.CurrentSplitIndex - 1;
            TimeSpan?curSegment = LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, state.CurrentTimingMethod);

            return(state.Run[splitIndex].BestSegmentTime[state.CurrentTimingMethod] == null || curSegment < state.Run[splitIndex].BestSegmentTime[state.CurrentTimingMethod]);
        }
예제 #4
0
        public string BuildMessage()
        {
            string ret       = Value;
            int    lastSplit = State.CurrentSplitIndex - 1;


            TimeSpan?deltaTime  = LiveSplitStateHelper.GetPreviousSegmentDelta(State, lastSplit, State.CurrentComparison, this.TimingMethod);
            TimeSpan?curSegment = LiveSplitStateHelper.GetPreviousSegmentTime(State, lastSplit, this.TimingMethod);

            if (!formatSet)
            {
                if (Accuracy == TimeAccuracy.Tenths)
                {
                    TimeFormat += "'.'f";
                }
                else if (Accuracy == TimeAccuracy.Hundredths)
                {
                    TimeFormat += "'.'ff";
                }
                else if (Accuracy == TimeAccuracy.Thousandths)
                {
                    TimeFormat += "'.'fff";
                }
                formatSet = true;
            }

            ret = ret.Replace("%t", curSegment.Value.ToString(TimeFormat));
            ret = ret.Replace("%n", State.Run[lastSplit].Name);
            if (deltaTime.HasValue)
            {
                ret = ret.Replace("%d", deltaTime.Value.ToString((deltaTime < TimeSpan.Zero ? "\\-" : "") + TimeFormat));
            }

            return(ret);
        }
예제 #5
0
 public bool CheckBestSegment(LiveSplitState state, int splitNumber, TimingMethod method)
 {
     if (Settings.ShowBestSegments)
     {
         return(LiveSplitStateHelper.CheckBestSegment(state, splitNumber, method));
     }
     return(false);
 }
        private string previousSegmentComponent()
        {
            var   comparison = State.CurrentComparison;
            var   method     = State.CurrentTimingMethod;
            var   text       = "Previous Segment";
            var   time       = "";
            Color?color      = Color.Transparent;

            TimeSpan?timeChange  = null;
            TimeSpan?timeSave    = null;
            var      liveSegment = LiveSplitStateHelper.CheckLiveDelta(State, false, comparison, method);

            if (State.CurrentPhase != TimerPhase.NotRunning)
            {
                if (liveSegment != null)
                {
                    timeChange = liveSegment;
                    timeSave   = GetPossibleTimeSave(State, State.CurrentSplitIndex, comparison);
                    text       = "Live Segment";
                }
                else if (State.CurrentSplitIndex > 0)
                {
                    timeChange = LiveSplitStateHelper.GetPreviousSegmentDelta(State, State.CurrentSplitIndex - 1, comparison, State.CurrentTimingMethod);
                    timeSave   = GetPossibleTimeSave(State, State.CurrentSplitIndex - 1, comparison);
                }
                if (timeChange != null)
                {
                    if (liveSegment != null)
                    {
                        color = LiveSplitStateHelper.GetSplitColor(State, timeChange, State.CurrentSplitIndex, false, false, comparison, method).Value;
                    }
                    else
                    {
                        color = LiveSplitStateHelper.GetSplitColor(State, timeChange.Value, State.CurrentSplitIndex - 1, false, true, comparison, method).Value;
                    }
                }
                else
                {
                    color = LiveSplitStateHelper.GetSplitColor(State, null, State.CurrentSplitIndex - 1, true, true, comparison, State.CurrentTimingMethod);
                    if (color == null)
                    {
                        color = State.LayoutSettings.TextColor;
                    }
                }
            }
            else
            {
                color = State.LayoutSettings.TextColor;
            }

            var a = DeltaFormatter.Accuracy;

            DeltaFormatter.Accuracy = TimeAccuracy.Tenths;
            time = DeltaFormatter.Format(timeChange);
            DeltaFormatter.Accuracy = a;

            return(formatInfoTextWithColor(text, time, color) + "\n");
        }
        public void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode)
        {
            var comparison = Settings.Comparison;

            if (!state.Run.Comparisons.Contains(comparison))
            {
                // #1682: Currently, support "Best Segments" comparison only ("Current Comparison" not supported)
                InternalComponent.InformationName = "Split #" + Settings.VisualCompareSplitNumber + " comparison not available";
                InternalComponent.TimeValue       = null;
            }
            else
            {
                if (Settings.VisualCompareSplitNumber > state.Run.Count)
                {
                    InternalComponent.InformationName = "Split #" + Settings.VisualCompareSplitNumber + " not available";
                    InternalComponent.TimeValue       = null;
                }
                else // get information for Settings.VisualCompareSplitNumber
                {
                    ISegment visualCompareSplitNumberSegment = state.Run[Settings.VisualCompareSplitNumber - 1];

                    if (state.CurrentSplitIndex > Settings.VisualCompareSplitNumber - 1)
                    {
                        InternalComponent.InformationName = "Time (" + visualCompareSplitNumberSegment.Name + ")";
                        InternalComponent.TimeValue       = visualCompareSplitNumberSegment.SplitTime[state.CurrentTimingMethod].GetValueOrDefault();
                    }
                    else
                    {
                        InternalComponent.InformationName = "Best Possible Time (" + visualCompareSplitNumberSegment.Name + ")";

                        if (state.CurrentPhase == TimerPhase.Running || state.CurrentPhase == TimerPhase.Paused)
                        {
                            TimeSpan?delta     = LiveSplitStateHelper.GetLastDelta(state, state.CurrentSplitIndex, comparison, state.CurrentTimingMethod) ?? TimeSpan.Zero;
                            var      liveDelta = state.CurrentTime[state.CurrentTimingMethod] - state.CurrentSplit.Comparisons[comparison][state.CurrentTimingMethod];
                            if (liveDelta > delta)
                            {
                                delta = liveDelta;
                            }
                            InternalComponent.TimeValue = delta + visualCompareSplitNumberSegment.Comparisons[comparison][state.CurrentTimingMethod];
                        }
                        else
                        {
                            TimeSpan?timeValue = visualCompareSplitNumberSegment.Comparisons[comparison][state.CurrentTimingMethod];
                            InternalComponent.TimeValue = timeValue;
                        }
                    }
                }
            }

            InternalComponent.Update(invalidator, state, width, height, mode);
        }
예제 #8
0
        public void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode)
        {
            var comparison = Settings.Comparison == "Current Comparison" ? state.CurrentComparison : Settings.Comparison;

            if (!state.Run.Comparisons.Contains(comparison))
            {
                comparison = state.CurrentComparison;
            }
            var comparisonName = comparison.StartsWith("[Race] ") ? comparison.Substring(7) : comparison;

            if (InternalComponent.InformationName != comparisonName)
            {
                InternalComponent.AlternateNameText.Clear();
                InternalComponent.AlternateNameText.Add(CompositeComparisons.GetShortComparisonName(comparison));
            }
            InternalComponent.LongestString   = comparisonName;
            InternalComponent.InformationName = comparisonName;

            var useLiveDelta = false;

            if (state.CurrentPhase == TimerPhase.Running || state.CurrentPhase == TimerPhase.Paused)
            {
                TimeSpan?delta     = LiveSplitStateHelper.GetLastDelta(state, state.CurrentSplitIndex, comparison, state.CurrentTimingMethod);
                var      liveDelta = state.CurrentTime[state.CurrentTimingMethod] - state.CurrentSplit.Comparisons[comparison][state.CurrentTimingMethod];
                if (liveDelta > delta || (delta == null && liveDelta > TimeSpan.Zero))
                {
                    delta        = liveDelta;
                    useLiveDelta = true;
                }
                InternalComponent.TimeValue = delta;
            }
            else if (state.CurrentPhase == TimerPhase.Ended)
            {
                InternalComponent.TimeValue = state.Run.Last().SplitTime[state.CurrentTimingMethod] - state.Run.Last().Comparisons[comparison][state.CurrentTimingMethod];
            }
            else
            {
                InternalComponent.TimeValue = null;
            }

            var color = LiveSplitStateHelper.GetSplitColor(state, InternalComponent.TimeValue, state.CurrentSplitIndex - (useLiveDelta ? 0 : 1), true, false, comparison, state.CurrentTimingMethod);

            if (color == null)
            {
                color = Settings.OverrideTextColor ? Settings.TextColor : state.LayoutSettings.TextColor;
            }
            InternalComponent.ValueLabel.ForeColor = color.Value;

            InternalComponent.Update(invalidator, state, width, height, mode);
        }
        private string splitComponent(ISegment segment, string comparison, TimingMethod method)
        {
            TimeSpan?deltaTime = null;
            Color?   color     = null;
            var      i         = State.Run.IndexOf(segment);
            int      delta     = 9;
            int      time      = 9;
            int      split     = Settings.CharacterWidth - delta - time - 2;
            var      segName   = (segment.Name.Length > split) ? segment.Name.Substring(0, split) : segment.Name;

            if (i < State.CurrentSplitIndex)
            {
                deltaTime = segment.SplitTime[method] - segment.Comparisons[comparison][method];
                color     = LiveSplitStateHelper.GetSplitColor(State, deltaTime, i, true, true, comparison, method);
            }
            else
            {
                //Live Delta
                var bestDelta = LiveSplitStateHelper.CheckLiveDelta(State, true, comparison, method);
                if (bestDelta != null && segment == State.CurrentSplit)
                {
                    deltaTime = bestDelta;
                    color     = State.LayoutSettings.TextColor;
                }
            }

            DeltaFormatter.DropDecimals = Settings.DropDecimals;
            DeltaFormatter.Accuracy     = Settings.DeltasAccuracy;
            SplitTimeFormatter.Accuracy = Settings.SplitAccuracy;

            var splitTime = segment.SplitTime[method];

            if (splitTime == null && State.CurrentSplitIndex <= i)
            {
                splitTime = segment.Comparisons[comparison][method];
            }

            return(String.Format("{0}{1, " + -split + "}<C> {2}{3, " + delta + "}<C> {4, " + time + "}\n",
                                 (State.CurrentSplit == segment) ? "<C8>" : "",
                                 segName,
                                 getColor(color),
                                 DeltaFormatter.Format(deltaTime),
                                 SplitTimeFormatter.Format(splitTime)
                                 ));
        }
예제 #10
0
        private SplitState GetSplitState(
            LiveSplitState state,
            TimeSpan?timeDifference,
            int splitNumber,
            string comparison,
            TimingMethod method)
        {
            SplitState splitState = SplitState.Unknown;

            if (splitNumber < 0)
            {
                return(splitState);
            }

            if (timeDifference != null)
            {
                if (timeDifference < TimeSpan.Zero)
                {
                    splitState = SplitState.AheadGaining;
                    var lastDelta = LiveSplitStateHelper.GetLastDelta(state, splitNumber - 1, comparison, method);
                    if (splitNumber > 0 && lastDelta != null && timeDifference > lastDelta)
                    {
                        splitState = SplitState.AheadLosing;
                    }
                }
                else
                {
                    splitState = SplitState.BehindLosing;
                    var lastDelta = LiveSplitStateHelper.GetLastDelta(state, splitNumber - 1, comparison, method);
                    if (splitNumber > 0 && lastDelta != null && timeDifference < lastDelta)
                    {
                        splitState = SplitState.BehindGaining;
                    }
                }
            }

            if (LiveSplitStateHelper.CheckBestSegment(state, splitNumber, method))
            {
                splitState = SplitState.BestSegment;
            }

            return(splitState);
        }
예제 #11
0
        public void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode)
        {
            var comparison = Settings.Comparison == "Current Comparison" ? state.CurrentComparison : Settings.Comparison;

            if (!state.Run.Comparisons.Contains(comparison))
            {
                comparison = state.CurrentComparison;
            }

            InternalComponent.InformationName = InternalComponent.LongestString = GetDisplayedName(comparison);

            if (InternalComponent.InformationName != PreviousInformationName)
            {
                SetAlternateText(comparison);
                PreviousInformationName = InternalComponent.InformationName;
            }

            if (InternalComponent.InformationName.StartsWith("Current Pace") && state.CurrentPhase == TimerPhase.NotRunning)
            {
                InternalComponent.TimeValue = null;
            }
            else if (state.CurrentPhase == TimerPhase.Running || state.CurrentPhase == TimerPhase.Paused)
            {
                TimeSpan?delta     = LiveSplitStateHelper.GetLastDelta(state, state.CurrentSplitIndex, comparison, state.CurrentTimingMethod) ?? TimeSpan.Zero;
                var      liveDelta = state.CurrentTime[state.CurrentTimingMethod] - state.CurrentSplit.Comparisons[comparison][state.CurrentTimingMethod];
                if (liveDelta > delta)
                {
                    delta = liveDelta;
                }
                InternalComponent.TimeValue = delta + state.Run.Last().Comparisons[comparison][state.CurrentTimingMethod];
            }
            else if (state.CurrentPhase == TimerPhase.Ended)
            {
                InternalComponent.TimeValue = state.Run.Last().SplitTime[state.CurrentTimingMethod];
            }
            else
            {
                InternalComponent.TimeValue = state.Run.Last().Comparisons[comparison][state.CurrentTimingMethod];
            }

            InternalComponent.Update(invalidator, state, width, height, mode);
        }
        private void ResolveForCount(IRun run)
        {
            int gold = 0, good = 0, bad = 0;
            foreach (ISegment segment in run)
            {
                var hasTime = segment.SplitTime[State.CurrentTimingMethod] != null;
                if (!hasTime)
                {
                    continue;
                }
                
                var wasGold = LiveSplitStateHelper.CheckBestSegment(State, run.IndexOf(segment), State.CurrentTimingMethod);
                var delta = LiveSplitStateHelper.GetPreviousSegmentDelta(State, run.IndexOf(segment),
                    State.CurrentComparison, State.CurrentTimingMethod);
                if (wasGold)
                {
                    gold++;
                }

                if (delta < TimeSpan.Zero)
                {
                    good++;
                }
                else
                {
                    bad++;
                }
            }

            if (Settings.ResolveOnGoldSplits)
            {
				_ = ResolveCurrentPredictionAsync(gold >= Settings.ResolveOnAmount);
            }
            else if (Settings.ResolveOnGoodSplits)
            {
				_ = ResolveCurrentPredictionAsync(good >= Settings.ResolveOnAmount);
            }
            else if (Settings.ResolveOnBadSplits)
            {
				_ = ResolveCurrentPredictionAsync(bad >= Settings.ResolveOnAmount);
            }
        }
예제 #13
0
        private static RunState GetRunState(LiveSplitState state, int splitIndex)
        {
            if (splitIndex < 0)
            {
                return(RunState.Indetermined);
            }

            TimeSpan?curSegment = LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, state.CurrentTimingMethod);

            if (curSegment != null)
            {
                if (state.Run[splitIndex].BestSegmentTime[state.CurrentTimingMethod] == null || curSegment < state.Run[splitIndex].BestSegmentTime[state.CurrentTimingMethod])
                {
                    return(RunState.BestSegment);
                }
            }

            var timeDifference = state.Run[splitIndex].SplitTime[state.CurrentTimingMethod] - state.Run[splitIndex].Comparisons[state.CurrentComparison][state.CurrentTimingMethod];

            if (timeDifference == null)
            {
                return(RunState.Indetermined);
            }

            if (timeDifference < TimeSpan.Zero)
            {
                if (LiveSplitStateHelper.GetPreviousSegmentDelta(state, splitIndex, state.CurrentComparison, state.CurrentTimingMethod) > TimeSpan.Zero)
                {
                    return(RunState.AheadLosing);
                }

                return(RunState.AheadGaining);
            }

            if (LiveSplitStateHelper.GetPreviousSegmentDelta(state, splitIndex, state.CurrentComparison, state.CurrentTimingMethod) < TimeSpan.Zero)
            {
                return(RunState.BehindGaining);
            }

            return(RunState.BehindLosing);
        }
예제 #14
0
 private TimeSpan?PredictTime(LiveSplitState state, string comparison)
 {
     if (state.CurrentPhase == TimerPhase.Running || state.CurrentPhase == TimerPhase.Paused)
     {
         TimeSpan?delta     = LiveSplitStateHelper.GetLastDelta(state, state.CurrentSplitIndex, comparison, State.CurrentTimingMethod) ?? TimeSpan.Zero;
         var      liveDelta = state.CurrentTime[State.CurrentTimingMethod] - state.CurrentSplit.Comparisons[comparison][State.CurrentTimingMethod];
         if (liveDelta > delta)
         {
             delta = liveDelta;
         }
         return(delta + state.Run.Last().Comparisons[comparison][State.CurrentTimingMethod]);
     }
     else if (state.CurrentPhase == TimerPhase.Ended)
     {
         return(state.Run.Last().SplitTime[State.CurrentTimingMethod]);
     }
     else
     {
         return(state.Run.Last().Comparisons[comparison][State.CurrentTimingMethod]);
     }
 }
예제 #15
0
        public TimeSpan?GetPossibleTimeSave(LiveSplitState state, ISegment segment, string comparison, bool live = false)
        {
            var      splitIndex   = state.Run.IndexOf(segment);
            var      prevTime     = TimeSpan.Zero;
            TimeSpan?bestSegments = state.Run[splitIndex].BestSegmentTime[state.CurrentTimingMethod];

            while (splitIndex > 0 && bestSegments != null)
            {
                var splitTime = state.Run[splitIndex - 1].Comparisons[comparison][state.CurrentTimingMethod];
                if (splitTime != null)
                {
                    prevTime = splitTime.Value;
                    break;
                }
                else
                {
                    splitIndex--;
                    bestSegments += state.Run[splitIndex].BestSegmentTime[state.CurrentTimingMethod];
                }
            }

            var time = segment.Comparisons[comparison][state.CurrentTimingMethod] - prevTime - bestSegments;

            if (live && splitIndex == state.CurrentSplitIndex)
            {
                var segmentDelta = TimeSpan.Zero - LiveSplitStateHelper.GetLiveSegmentDelta(state, state.Run.IndexOf(segment), comparison, state.CurrentTimingMethod);
                if (segmentDelta < time)
                {
                    time = segmentDelta;
                }
            }

            if (time < TimeSpan.Zero)
            {
                time = TimeSpan.Zero;
            }

            return(time);
        }
        private SplitColour calculateNonGoldSplitColour()
        {
            int      splitIndex          = state.CurrentSplitIndex - 1;
            TimeSpan?splitTime           = state.Run[splitIndex].SplitTime[state.CurrentTimingMethod];
            TimeSpan?comparisonSplitTime = state.Run[splitIndex].Comparisons[state.CurrentComparison][state.CurrentTimingMethod];
            TimeSpan?totalRunDifference  = splitTime - comparisonSplitTime;

            TimeSpan?previousSegmentDifference = LiveSplitStateHelper.GetPreviousSegmentDelta(state, splitIndex, state.CurrentComparison, state.CurrentTimingMethod);

            if (totalRunDifference < TimeSpan.Zero)
            {
                if (previousSegmentDifference < TimeSpan.Zero)
                {
                    return(SplitColour.DARK_GREEN);
                }
                return(SplitColour.LIGHT_GREEN);
            }

            if (previousSegmentDifference < TimeSpan.Zero)
            {
                return(SplitColour.LIGHT_RED);
            }
            return(SplitColour.DARK_RED);
        }
예제 #17
0
 private void ProcessMessage(String message, Connection clientConnection)
 {
     try
     {
         if (message == "startorsplit")
         {
             if (State.CurrentPhase == TimerPhase.Running)
             {
                 Model.Split();
             }
             else
             {
                 Model.Start();
             }
         }
         else if (message == "split")
         {
             Model.Split();
         }
         else if (message == "unsplit")
         {
             Model.UndoSplit();
         }
         else if (message == "skipsplit")
         {
             Model.SkipSplit();
         }
         else if (message == "pause" && State.CurrentPhase != TimerPhase.Paused)
         {
             Model.Pause();
         }
         else if (message == "resume" && State.CurrentPhase == TimerPhase.Paused)
         {
             Model.Pause();
         }
         else if (message == "reset")
         {
             Model.Reset();
         }
         else if (message == "starttimer")
         {
             Model.Start();
         }
         else if (message.StartsWith("setgametime "))
         {
             var value = message.Split(' ')[1];
             var time  = parseTime(value);
             State.SetGameTime(time);
         }
         else if (message.StartsWith("setloadingtimes "))
         {
             var value = message.Split(' ')[1];
             var time  = parseTime(value);
             State.LoadingTimes = time ?? TimeSpan.Zero;
         }
         else if (message == "pausegametime")
         {
             State.IsGameTimePaused = true;
         }
         else if (message == "unpausegametime")
         {
             AlwaysPauseGameTime    = false;
             State.IsGameTimePaused = false;
         }
         else if (message == "alwayspausegametime")
         {
             AlwaysPauseGameTime    = true;
             State.IsGameTimePaused = true;
         }
         else if (message == "getdelta" || message.StartsWith("getdelta "))
         {
             var comparison = State.CurrentComparison;
             if (message.Contains(" "))
             {
                 comparison = message.Split(new char[] { ' ' }, 2)[1];
             }
             var delta    = LiveSplitStateHelper.GetLastDelta(State, State.CurrentSplitIndex, comparison, State.CurrentTimingMethod);
             var response = DeltaFormatter.Format(delta);
             clientConnection.SendMessage(response);
         }
         else if (message == "getsplitindex")
         {
             var splitindex = State.CurrentSplitIndex;
             var response   = splitindex.ToString();
             clientConnection.SendMessage(response);
         }
         else if (message == "getcurrentsplitname")
         {
             var splitindex       = State.CurrentSplitIndex;
             var currentsplitname = State.CurrentSplit.Name;
             var response         = currentsplitname;
             clientConnection.SendMessage(response);
         }
         else if (message == "getprevioussplitname")
         {
             var previoussplitindex = State.CurrentSplitIndex - 1;
             var previoussplitname  = State.Run[previoussplitindex].Name;
             var response           = previoussplitname;
             clientConnection.SendMessage(response);
         }
         else if (message == "getlastsplittime" && State.CurrentSplitIndex > 0)
         {
             var splittime = State.Run[State.CurrentSplitIndex - 1].SplitTime[State.CurrentTimingMethod];
             var response  = SplitTimeFormatter.Format(splittime);
             clientConnection.SendMessage(response);
         }
         else if (message == "getcomparisonsplittime")
         {
             var splittime = State.CurrentSplit.Comparisons[State.CurrentComparison][State.CurrentTimingMethod];
             var response  = SplitTimeFormatter.Format(splittime);
             clientConnection.SendMessage(response);
         }
         else if (message == "getcurrentrealtime")
         {
             var time     = State.CurrentTime.RealTime;
             var response = SplitTimeFormatter.Format(time);
             clientConnection.SendMessage(response);
         }
         else if (message == "getcurrentgametime")
         {
             var timingMethod = TimingMethod.GameTime;
             if (!State.IsGameTimeInitialized)
             {
                 timingMethod = TimingMethod.RealTime;
             }
             var time     = State.CurrentTime[timingMethod];
             var response = SplitTimeFormatter.Format(time);
             clientConnection.SendMessage(response);
         }
         else if (message == "getcurrenttime")
         {
             var timingMethod = State.CurrentTimingMethod;
             if (timingMethod == TimingMethod.GameTime && !State.IsGameTimeInitialized)
             {
                 timingMethod = TimingMethod.RealTime;
             }
             var time     = State.CurrentTime[timingMethod];
             var response = SplitTimeFormatter.Format(time);
             clientConnection.SendMessage(response);
         }
         else if (message == "getfinaltime" || message.StartsWith("getfinaltime "))
         {
             var comparison = State.CurrentComparison;
             if (message.Contains(" "))
             {
                 comparison = message.Split(new char[] { ' ' }, 2)[1];
             }
             var time = (State.CurrentPhase == TimerPhase.Ended)
                 ? State.CurrentTime[State.CurrentTimingMethod]
                 : State.Run.Last().Comparisons[comparison][State.CurrentTimingMethod];
             var response = SplitTimeFormatter.Format(time);
             clientConnection.SendMessage(response);
         }
         else if (message.StartsWith("getpredictedtime "))
         {
             var comparison = message.Split(new char[] { ' ' }, 2)[1];
             var prediction = PredictTime(State, comparison);
             var response   = SplitTimeFormatter.Format(prediction);
             clientConnection.SendMessage(response);
         }
         else if (message == "getbestpossibletime")
         {
             var comparison = LiveSplit.Model.Comparisons.BestSegmentsComparisonGenerator.ComparisonName;
             var prediction = PredictTime(State, comparison);
             var response   = SplitTimeFormatter.Format(prediction);
             clientConnection.SendMessage(response);
         }
         else if (message == "getcurrenttimerphase")
         {
             var response = State.CurrentPhase.ToString();
             clientConnection.SendMessage(response);
         }
         else if (message.StartsWith("setcomparison "))
         {
             var comparison = message.Split(new char[] { ' ' }, 2)[1];
             State.CurrentComparison = comparison;
         }
         else if (message == "switchto realtime")
         {
             State.CurrentTimingMethod = TimingMethod.RealTime;
         }
         else if (message == "switchto gametime")
         {
             State.CurrentTimingMethod = TimingMethod.GameTime;
         }
         else if (message.StartsWith("setsplitname "))
         {
             int    index = Convert.ToInt32(message.Split(new char[] { ' ' }, 3)[1]);
             string title = message.Split(new char[] { ' ' }, 3)[2];
             State.Run[index].Name = title;
             State.Run.HasChanged  = true;
         }
         else if (message.StartsWith("setcurrentsplitname "))
         {
             string title = message.Split(new char[] { ' ' }, 2)[1];
             State.Run[State.CurrentSplitIndex].Name = title;
             State.Run.HasChanged = true;
         }
     }
     catch (Exception ex)
     {
         Log.Error(ex);
     }
 }
예제 #18
0
        private void State_OnSplit(object sender, EventArgs e)
        {
            if (State.CurrentPhase == TimerPhase.Ended)
            {
                if (State.Run.Last().PersonalBestSplitTime[State.CurrentTimingMethod] == null || State.Run.Last().SplitTime[State.CurrentTimingMethod] < State.Run.Last().PersonalBestSplitTime[State.CurrentTimingMethod])
                {
                    PlaySound(Settings.PersonalBest, Settings.PersonalBestVolume);
                }
                else
                {
                    PlaySound(Settings.NotAPersonalBest, Settings.NotAPersonalBestVolume);
                }
            }
            else
            {
                var path   = string.Empty;
                int volume = Settings.SplitVolume;

                var splitIndex     = State.CurrentSplitIndex - 1;
                var timeDifference = State.Run[splitIndex].SplitTime[State.CurrentTimingMethod] - State.Run[splitIndex].Comparisons[State.CurrentComparison][State.CurrentTimingMethod];

                if (timeDifference != null)
                {
                    if (timeDifference < TimeSpan.Zero)
                    {
                        path   = Settings.SplitAheadGaining;
                        volume = Settings.SplitAheadGainingVolume;

                        if (LiveSplitStateHelper.GetPreviousSegmentDelta(State, splitIndex, State.CurrentComparison, State.CurrentTimingMethod) > TimeSpan.Zero)
                        {
                            path   = Settings.SplitAheadLosing;
                            volume = Settings.SplitAheadLosingVolume;
                        }
                    }
                    else
                    {
                        path   = Settings.SplitBehindLosing;
                        volume = Settings.SplitBehindLosingVolume;

                        if (LiveSplitStateHelper.GetPreviousSegmentDelta(State, splitIndex, State.CurrentComparison, State.CurrentTimingMethod) < TimeSpan.Zero)
                        {
                            path   = Settings.SplitBehindGaining;
                            volume = Settings.SplitBehindGainingVolume;
                        }
                    }
                }

                //Check for best segment
                TimeSpan?curSegment = LiveSplitStateHelper.GetPreviousSegmentTime(State, splitIndex, State.CurrentTimingMethod);

                if (curSegment != null)
                {
                    if (State.Run[splitIndex].BestSegmentTime[State.CurrentTimingMethod] == null || curSegment < State.Run[splitIndex].BestSegmentTime[State.CurrentTimingMethod])
                    {
                        path   = Settings.BestSegment;
                        volume = Settings.BestSegmentVolume;
                    }
                }

                if (string.IsNullOrEmpty(path))
                {
                    path = Settings.Split;
                }

                PlaySound(path, volume);
            }
        }
        private string timerComponent()
        {
            UpdateTimeFormat();
            var timingMethod = State.CurrentTimingMethod;

            if (Settings.TimingMethod == "Real Time")
            {
                timingMethod = TimingMethod.RealTime;
            }
            else if (Settings.TimingMethod == "Game Time")
            {
                timingMethod = TimingMethod.GameTime;
            }

            var comparison = State.CurrentComparison;
            var method     = State.CurrentTimingMethod;
            var TimerColor = Color.Transparent;

            if (State.CurrentPhase == TimerPhase.NotRunning || State.CurrentTime[method] < TimeSpan.Zero)
            {
                TimerColor = State.LayoutSettings.NotRunningColor;
            }
            else if (State.CurrentPhase == TimerPhase.Paused)
            {
                TimerColor = State.LayoutSettings.PausedColor;
            }
            else if (State.CurrentPhase == TimerPhase.Ended)
            {
                if (State.Run.Last().Comparisons[State.CurrentComparison][method] == null || State.CurrentTime[method] < State.Run.Last().Comparisons[State.CurrentComparison][method])
                {
                    TimerColor = State.LayoutSettings.PersonalBestColor;
                }
                else
                {
                    TimerColor = State.LayoutSettings.BehindLosingTimeColor;
                }
            }
            else if (State.CurrentPhase == TimerPhase.Running)
            {
                if (State.CurrentSplit.Comparisons[State.CurrentComparison][method] != null)
                {
                    TimerColor = LiveSplitStateHelper.GetSplitColor(State, State.CurrentTime[method] - State.CurrentSplit.Comparisons[State.CurrentComparison][method],
                                                                    State.CurrentSplitIndex, true, false, State.CurrentComparison, method)
                                 ?? State.LayoutSettings.AheadGainingTimeColor;
                }
                else
                {
                    TimerColor = State.LayoutSettings.AheadGainingTimeColor;
                }
            }

            var timeValue  = State.CurrentTime[timingMethod];
            var timeString = ShortFormatter.Format(timeValue, CurrentTimeFormat);
            int dotIndex   = timeString.IndexOf(".");
            var time       = timeString.Substring(0, dotIndex);
            var fraction   = String.Empty;

            if (CurrentAccuracy == TimeAccuracy.Hundredths)
            {
                fraction = timeString.Substring(dotIndex);
            }
            else if (CurrentAccuracy == TimeAccuracy.Tenths)
            {
                fraction = timeString.Substring(dotIndex, 2);
            }

            return(String.Format("{0}{1, " + Settings.CharacterWidth + "}<C>\n",
                                 getColor(TimerColor),
                                 String.Join("", time, fraction)));
        }
예제 #20
0
        private Image GetIcon(LiveSplitState state, int splitIndex, out bool customizedIcon)
        {
            var icon = Split.Icon;

            customizedIcon = true;

            if (this.Settings.DisplayIcons)
            {
                var attemptIconOverride        = false;
                var currentSegmantHasBeenSplit = (state.CurrentSplitIndex > splitIndex);
                var updateBasedOnCurrentRun    = (this.Settings.GradedIconsApplicationState == GradedIconsApplicationState.ComparisonAndCurrentRun ||
                                                  this.Settings.GradedIconsApplicationState == GradedIconsApplicationState.CurrentRun);

                var updateBasedOnComparison = (this.Settings.GradedIconsApplicationState == GradedIconsApplicationState.ComparisonAndCurrentRun ||
                                               this.Settings.GradedIconsApplicationState == GradedIconsApplicationState.Comparison);

                if (updateBasedOnComparison)
                {
                    attemptIconOverride = true;
                }
                else if (updateBasedOnCurrentRun && currentSegmantHasBeenSplit)
                {
                    attemptIconOverride = true;
                }

                // If this split has already gone past:
                if (attemptIconOverride)
                {
                    var splitState          = SplitState.Unknown;
                    var previousSegmentTime = LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, state.CurrentTimingMethod);

                    var overrideAsSkippedPBSplit = false;

                    // Use the skipped split icon if they specified to override for the current run
                    // if the segment has been split (and skipped)
                    if (previousSegmentTime == null &&
                        currentSegmantHasBeenSplit &&
                        updateBasedOnCurrentRun)
                    {
                        overrideAsSkippedPBSplit = true;
                    }
                    // Use the skipped split icon if they specified to override compared to the PB
                    else if (updateBasedOnComparison)
                    {
                        // Don't override whatever's in PB if they've split this segment and specificed to update on teh current run
                        // We don't want a skipped PB segment to cause a "return" later on here.
                        if (!(currentSegmantHasBeenSplit && updateBasedOnCurrentRun))
                        {
                            // the PB was a skipped split?
                            var PBSplit = state.Run[splitIndex];
                            if (PBSplit != null)
                            {
                                var PBSplittime = PBSplit.PersonalBestSplitTime;
                                if (state.CurrentTimingMethod == TimingMethod.GameTime)
                                {
                                    overrideAsSkippedPBSplit = (PBSplittime.GameTime == null);
                                }
                                else if (state.CurrentTimingMethod == TimingMethod.RealTime)
                                {
                                    overrideAsSkippedPBSplit = (PBSplittime.RealTime == null);
                                }
                            }
                        }
                    }

                    if (overrideAsSkippedPBSplit &&
                        this.Settings.SkippedSplitIcon != null &&
                        this.Settings.SkippedSplitIcon.IconState == GradedIconState.Default)
                    {
                        if (string.IsNullOrWhiteSpace(this.Settings.SkippedSplitIcon.Base64Bytes))
                        {
                            icon = null;
                        }
                        else
                        {
                            // It was a skipped split
                            Image cached;
                            if (!GradedIcons.TryGetValue(this.Settings.SkippedSplitIcon.Base64Bytes + "_ss", out cached))
                            {
                                icon = getBitmapFromBase64(this.Settings.SkippedSplitIcon.Base64Bytes);
                                GradedIcons.Add(this.Settings.SkippedSplitIcon.Base64Bytes + "_ss", icon);
                            }
                            else
                            {
                                icon = cached;
                            }
                        }

                        customizedIcon = true;
                        return(icon);
                    }


                    var getCurrentSplitPercentageBehindBestSegment = new Func <decimal>(() =>
                    {
                        // say your best segment is 100s
                        // it makes sense to do like < 105 = A
                        // < 110 = B
                        // 0.05 = (105-100)/100
                        double bestMilliseconds = 0;
                        if (state.CurrentTimingMethod == TimingMethod.GameTime)
                        {
                            bestMilliseconds = Split.BestSegmentTime.GameTime?.TotalMilliseconds ?? 0;
                        }
                        else if (state.CurrentTimingMethod == TimingMethod.RealTime)
                        {
                            bestMilliseconds = Split.BestSegmentTime.RealTime?.TotalMilliseconds ?? 0;
                        }

                        // No current best segment, gold split guaranteed A+?
                        if (bestMilliseconds <= 0)
                        {
                            return(0);
                        }

                        double currentMilliseconds = 0;
                        if (currentSegmantHasBeenSplit && updateBasedOnCurrentRun)
                        {
                            if (previousSegmentTime != null)
                            {
                                currentMilliseconds = previousSegmentTime.Value.TotalMilliseconds;
                            }
                        }
                        else
                        {
                            double personalBestTimeMilliseconds = 0;
                            double priorsplitMilliseconds       = 0;
                            if (state.CurrentTimingMethod == TimingMethod.GameTime)
                            {
                                personalBestTimeMilliseconds = Split.PersonalBestSplitTime.GameTime?.TotalMilliseconds ?? 0;
                                if (splitIndex > 0) // At index 0, there is no prior split, and the PB split IS the total ms for it
                                {
                                    priorsplitMilliseconds = state.Run[splitIndex - 1].PersonalBestSplitTime.GameTime?.TotalMilliseconds ?? 0;
                                }
                            }
                            else if (state.CurrentTimingMethod == TimingMethod.RealTime)
                            {
                                personalBestTimeMilliseconds = Split.PersonalBestSplitTime.RealTime?.TotalMilliseconds ?? 0;
                                if (splitIndex > 0) // At index 0, there is no prior split, and the PB split IS the total ms for it
                                {
                                    priorsplitMilliseconds = state.Run[splitIndex - 1].PersonalBestSplitTime.RealTime?.TotalMilliseconds ?? 0;
                                }
                            }

                            currentMilliseconds = (personalBestTimeMilliseconds - priorsplitMilliseconds);
                        }

                        // you were super amazing or i messed up:
                        if (currentMilliseconds <= 0)
                        {
                            return(-1);
                        }

                        return(Convert.ToDecimal((((currentMilliseconds - bestMilliseconds) / bestMilliseconds) * ((double)100))));
                    });

                    if ((!string.IsNullOrWhiteSpace(this.Settings.BehindLosingTimeIcon.Base64Bytes) &&
                         this.Settings.BehindLosingTimeIcon.IconState == GradedIconState.Default) ||
                        (!string.IsNullOrWhiteSpace(this.Settings.BehindGainingTimeIcon.Base64Bytes) &&
                         this.Settings.BehindGainingTimeIcon.IconState == GradedIconState.Default) ||
                        (!string.IsNullOrWhiteSpace(this.Settings.AheadLosingTimeIcon.Base64Bytes) &&
                         this.Settings.AheadLosingTimeIcon.IconState == GradedIconState.Default) ||
                        (!string.IsNullOrWhiteSpace(this.Settings.AheadGainingTimeIcon.Base64Bytes) &&
                         this.Settings.AheadGainingTimeIcon.IconState == GradedIconState.Default) ||
                        (!string.IsNullOrWhiteSpace(this.Settings.BestSegmentIcon.Base64Bytes) &&
                         this.Settings.BestSegmentIcon.IconState == GradedIconState.Default))
                    {
                        var segmentDelta = LiveSplitStateHelper.GetPreviousSegmentDelta(state, splitIndex, state.CurrentComparison, state.CurrentTimingMethod);
                        splitState = this.GetSplitState(state, segmentDelta, splitIndex, state.CurrentComparison, state.CurrentTimingMethod);
                    }

                    var iconToUse = SplitState.Unknown;

                    if (!string.IsNullOrWhiteSpace(this.Settings.BehindLosingTimeIcon.Base64Bytes) &&
                        this.Settings.BehindLosingTimeIcon.IconState != GradedIconState.Disabled)
                    {
                        if (this.Settings.BehindLosingTimeIcon.IconState == GradedIconState.Default && splitState == SplitState.BehindLosing)
                        {
                            iconToUse = splitState;
                        }
                        else if (this.Settings.BehindLosingTimeIcon.IconState == GradedIconState.PercentageSplit)
                        {
                            var percentage = getCurrentSplitPercentageBehindBestSegment();
                            if (percentage < this.Settings.BehindLosingTimeIcon.PercentageBehind)
                            {
                                iconToUse = SplitState.BehindLosing;
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(this.Settings.BehindGainingTimeIcon.Base64Bytes) &&
                        this.Settings.BehindGainingTimeIcon.IconState != GradedIconState.Disabled)
                    {
                        if (this.Settings.BehindGainingTimeIcon.IconState == GradedIconState.Default && splitState == SplitState.BehindGaining)
                        {
                            iconToUse = splitState;
                        }
                        else if (this.Settings.BehindGainingTimeIcon.IconState == GradedIconState.PercentageSplit)
                        {
                            var percentage = getCurrentSplitPercentageBehindBestSegment();
                            if (percentage < this.Settings.BehindGainingTimeIcon.PercentageBehind)
                            {
                                iconToUse = SplitState.BehindGaining;
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(this.Settings.AheadLosingTimeIcon.Base64Bytes) &&
                        this.Settings.AheadLosingTimeIcon.IconState != GradedIconState.Disabled)
                    {
                        if (this.Settings.AheadLosingTimeIcon.IconState == GradedIconState.Default && splitState == SplitState.AheadLosing)
                        {
                            iconToUse = splitState;
                        }
                        else if (this.Settings.AheadLosingTimeIcon.IconState == GradedIconState.PercentageSplit)
                        {
                            var percentage = getCurrentSplitPercentageBehindBestSegment();
                            if (percentage < this.Settings.AheadLosingTimeIcon.PercentageBehind)
                            {
                                iconToUse = SplitState.AheadLosing;
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(this.Settings.AheadGainingTimeIcon.Base64Bytes) &&
                        this.Settings.AheadGainingTimeIcon.IconState != GradedIconState.Disabled)
                    {
                        if (this.Settings.AheadGainingTimeIcon.IconState == GradedIconState.Default && splitState == SplitState.AheadGaining)
                        {
                            iconToUse = splitState;
                        }
                        else if (this.Settings.AheadGainingTimeIcon.IconState == GradedIconState.PercentageSplit)
                        {
                            var percentage = getCurrentSplitPercentageBehindBestSegment();
                            if (percentage < this.Settings.AheadGainingTimeIcon.PercentageBehind)
                            {
                                iconToUse = SplitState.AheadGaining;
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(this.Settings.BestSegmentIcon.Base64Bytes) &&
                        this.Settings.BestSegmentIcon.IconState != GradedIconState.Disabled)
                    {
                        if (this.Settings.BestSegmentIcon.IconState == GradedIconState.Default && splitState == SplitState.BestSegment)
                        {
                            iconToUse = splitState;
                        }
                        else if (this.Settings.BestSegmentIcon.IconState == GradedIconState.PercentageSplit)
                        {
                            var percentage = getCurrentSplitPercentageBehindBestSegment();

                            if (percentage < this.Settings.BestSegmentIcon.PercentageBehind)
                            {
                                iconToUse = SplitState.BestSegment;
                            }
                        }
                    }

                    if (iconToUse == SplitState.BestSegment)
                    {
                        Image cached;
                        if (!GradedIcons.TryGetValue(this.Settings.BestSegmentIcon.Base64Bytes + "_1", out cached))
                        {
                            icon = getBitmapFromBase64(this.Settings.BestSegmentIcon.Base64Bytes);
                            GradedIcons.Add(this.Settings.BestSegmentIcon.Base64Bytes + "_1", icon);
                        }
                        else
                        {
                            icon = cached;
                        }

                        customizedIcon = true;
                    }
                    else if (iconToUse == SplitState.AheadGaining)
                    {
                        Image cached;
                        if (!GradedIcons.TryGetValue(this.Settings.AheadGainingTimeIcon.Base64Bytes + "_2", out cached))
                        {
                            icon = getBitmapFromBase64(this.Settings.AheadGainingTimeIcon.Base64Bytes);
                            GradedIcons.Add(this.Settings.AheadGainingTimeIcon.Base64Bytes + "_2", icon);
                        }
                        else
                        {
                            icon = cached;
                        }

                        customizedIcon = true;
                    }
                    else if (iconToUse == SplitState.AheadLosing)
                    {
                        Image cached;
                        if (!GradedIcons.TryGetValue(this.Settings.AheadLosingTimeIcon.Base64Bytes + "_3", out cached))
                        {
                            icon = getBitmapFromBase64(this.Settings.AheadLosingTimeIcon.Base64Bytes);
                            GradedIcons.Add(this.Settings.AheadLosingTimeIcon.Base64Bytes + "_3", icon);
                        }
                        else
                        {
                            icon = cached;
                        }

                        customizedIcon = true;
                    }
                    else if (iconToUse == SplitState.BehindGaining)
                    {
                        Image cached;
                        if (!GradedIcons.TryGetValue(this.Settings.BehindGainingTimeIcon.Base64Bytes + "_4", out cached))
                        {
                            icon = getBitmapFromBase64(this.Settings.BehindGainingTimeIcon.Base64Bytes);
                            GradedIcons.Add(this.Settings.BehindGainingTimeIcon.Base64Bytes + "_4", icon);
                        }
                        else
                        {
                            icon = cached;
                        }

                        customizedIcon = true;
                    }
                    else if (iconToUse == SplitState.BehindLosing)
                    {
                        Image cached;
                        if (!GradedIcons.TryGetValue(this.Settings.BehindLosingTimeIcon.Base64Bytes + "_5", out cached))
                        {
                            icon = getBitmapFromBase64(this.Settings.BehindLosingTimeIcon.Base64Bytes);
                            GradedIcons.Add(this.Settings.BehindLosingTimeIcon.Base64Bytes + "_5", icon);
                        }
                        else
                        {
                            icon = cached;
                        }

                        customizedIcon = true;
                    }
                }
            }

            return(icon);
        }
예제 #21
0
        protected void UpdateColumn(LiveSplitState state, SimpleLabel label, ColumnData data)
        {
            var comparison = data.Comparison == "Current Comparison" ? state.CurrentComparison : data.Comparison;

            if (!state.Run.Comparisons.Contains(comparison))
            {
                comparison = state.CurrentComparison;
            }

            var timingMethod = state.CurrentTimingMethod;

            if (data.TimingMethod == "Real Time")
            {
                timingMethod = TimingMethod.RealTime;
            }
            else if (data.TimingMethod == "Game Time")
            {
                timingMethod = TimingMethod.GameTime;
            }

            var type = data.Type;

            var splitIndex = state.Run.IndexOf(Split);

            if (splitIndex < state.CurrentSplitIndex)
            {
                if (type == ColumnType.SplitTime || type == ColumnType.SegmentTime)
                {
                    label.ForeColor = Settings.OverrideTimesColor ? Settings.BeforeTimesColor : state.LayoutSettings.TextColor;

                    if (type == ColumnType.SplitTime)
                    {
                        label.Text = TimeFormatter.Format(Split.SplitTime[timingMethod]);
                    }
                    else //SegmentTime
                    {
                        var segmentTime = LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, timingMethod);
                        label.Text = TimeFormatter.Format(segmentTime);
                    }
                }

                if (type == ColumnType.DeltaorSplitTime || type == ColumnType.Delta)
                {
                    var deltaTime = Split.SplitTime[timingMethod] - Split.Comparisons[comparison][timingMethod];
                    var color     = LiveSplitStateHelper.GetSplitColor(state, deltaTime, splitIndex, true, true, comparison, timingMethod);
                    if (color == null)
                    {
                        color = Settings.OverrideTimesColor ? Settings.BeforeTimesColor : state.LayoutSettings.TextColor;
                    }
                    label.ForeColor = color.Value;

                    if (type == ColumnType.DeltaorSplitTime)
                    {
                        if (deltaTime != null)
                        {
                            label.Text = DeltaTimeFormatter.Format(deltaTime);
                        }
                        else
                        {
                            label.Text = TimeFormatter.Format(Split.SplitTime[timingMethod]);
                        }
                    }
                    else if (type == ColumnType.Delta)
                    {
                        label.Text = DeltaTimeFormatter.Format(deltaTime);
                    }
                }
                else if (type == ColumnType.SegmentDeltaorSegmentTime || type == ColumnType.SegmentDelta)
                {
                    var segmentDelta = LiveSplitStateHelper.GetPreviousSegmentDelta(state, splitIndex, comparison, timingMethod);
                    var color        = LiveSplitStateHelper.GetSplitColor(state, segmentDelta, splitIndex, false, true, comparison, timingMethod);
                    if (color == null)
                    {
                        color = Settings.OverrideTimesColor ? Settings.BeforeTimesColor : state.LayoutSettings.TextColor;
                    }
                    label.ForeColor = color.Value;

                    if (type == ColumnType.SegmentDeltaorSegmentTime)
                    {
                        if (segmentDelta != null)
                        {
                            label.Text = DeltaTimeFormatter.Format(segmentDelta);
                        }
                        else
                        {
                            label.Text = TimeFormatter.Format(LiveSplitStateHelper.GetPreviousSegmentTime(state, splitIndex, timingMethod));
                        }
                    }
                    else if (type == ColumnType.SegmentDelta)
                    {
                        label.Text = DeltaTimeFormatter.Format(segmentDelta);
                    }
                }
            }
            else
            {
                if (type == ColumnType.SplitTime || type == ColumnType.SegmentTime || type == ColumnType.DeltaorSplitTime || type == ColumnType.SegmentDeltaorSegmentTime)
                {
                    if (Split == state.CurrentSplit)
                    {
                        label.ForeColor = Settings.OverrideTimesColor ? Settings.CurrentTimesColor : state.LayoutSettings.TextColor;
                    }
                    else
                    {
                        label.ForeColor = Settings.OverrideTimesColor ? Settings.AfterTimesColor : state.LayoutSettings.TextColor;
                    }

                    if (type == ColumnType.SplitTime || type == ColumnType.DeltaorSplitTime)
                    {
                        label.Text = TimeFormatter.Format(Split.Comparisons[comparison][timingMethod]);
                    }
                    else //SegmentTime or SegmentTimeorSegmentDeltaTime
                    {
                        var previousTime = TimeSpan.Zero;
                        for (var index = splitIndex - 1; index >= 0; index--)
                        {
                            var comparisonTime = state.Run[index].Comparisons[comparison][timingMethod];
                            if (comparisonTime != null)
                            {
                                previousTime = comparisonTime.Value;
                                break;
                            }
                        }
                        label.Text = TimeFormatter.Format(Split.Comparisons[comparison][timingMethod] - previousTime);
                    }
                }

                //Live Delta
                var splitDelta = type == ColumnType.DeltaorSplitTime || type == ColumnType.Delta;
                var bestDelta  = LiveSplitStateHelper.CheckLiveDelta(state, splitDelta, comparison, timingMethod);
                if (bestDelta != null && Split == state.CurrentSplit &&
                    (type == ColumnType.DeltaorSplitTime || type == ColumnType.Delta || type == ColumnType.SegmentDeltaorSegmentTime || type == ColumnType.SegmentDelta))
                {
                    if (splitDelta) //DeltaorSplitTime or Delta
                    {
                        label.Text = DeltaTimeFormatter.Format(bestDelta);
                    }
                    else //SegmentDeltaorSegmentTime or SegmentDelta
                    {
                        label.Text = DeltaTimeFormatter.Format(LiveSplitStateHelper.GetLiveSegmentDelta(state, splitIndex, comparison, timingMethod));
                    }

                    label.ForeColor = Settings.OverrideDeltasColor ? Settings.DeltasColor : state.LayoutSettings.TextColor;
                }
                else if (type == ColumnType.Delta || type == ColumnType.SegmentDelta)
                {
                    label.Text = "";
                }
            }
        }
예제 #22
0
        private void ProcessMessage(String message, string[] arguments, Connection clientConnection)
        {
            try
            {
                if (message == "registerEvent")
                {
                    if (arguments.Length == 0)
                    {
                    }
                    foreach (string ev in arguments)
                    {
                        dynamic handler;
                        switch (ev)
                        {
                        case "pause":
                            handler = new EventHandler((object o, EventArgs e) =>
                            {
                                clientConnection.SendMessage(ev);
                            });
                            State.OnPause += handler;
                            clientConnection.addDisconnectHandler(() => State.OnPause -= handler);
                            break;

                        case "reset":
                            handler = new EventHandlerT <TimerPhase>((object o, TimerPhase e) =>
                            {
                                clientConnection.SendMessage(ev, e.ToString());
                            });
                            State.OnReset += handler;
                            clientConnection.addDisconnectHandler(() => State.OnReset -= handler);
                            break;

                        case "resume":
                            handler = new EventHandler((object o, EventArgs e) =>
                            {
                                clientConnection.SendMessage(ev);
                            });
                            State.OnResume += handler;
                            clientConnection.addDisconnectHandler(() => State.OnResume -= handler);
                            break;

                        case "skipSplit":
                            handler = new EventHandler((object o, EventArgs e) =>
                            {
                                clientConnection.SendMessage(ev);
                            });
                            State.OnSkipSplit += handler;
                            clientConnection.addDisconnectHandler(() => State.OnSkipSplit -= handler);
                            break;

                        case "split":
                            handler = new EventHandler((object o, EventArgs e) =>
                            {
                                clientConnection.SendMessage(ev);
                            });
                            State.OnSplit += handler;
                            clientConnection.addDisconnectHandler(() => State.OnSplit -= handler);
                            break;

                        case "start":
                            handler = new EventHandler((object o, EventArgs e) =>
                            {
                                clientConnection.SendMessage(ev);
                            });
                            State.OnStart += handler;
                            clientConnection.addDisconnectHandler(() => State.OnStart -= handler);
                            break;

                        case "switchComparison":
                            handler = new EventHandler((object o, EventArgs e) =>
                            {
                                clientConnection.SendMessage(ev, State.CurrentComparison);
                            });
                            State.OnSwitchComparisonNext     += handler;
                            State.OnSwitchComparisonPrevious += handler;
                            clientConnection.addDisconnectHandler(() =>
                            {
                                State.OnSwitchComparisonNext     -= handler;
                                State.OnSwitchComparisonPrevious -= handler;
                            });
                            break;

                        case "undoAllPauses":
                            handler = new EventHandler((object o, EventArgs e) =>
                            {
                                clientConnection.SendMessage(ev);
                            });
                            State.OnUndoAllPauses += handler;
                            clientConnection.addDisconnectHandler(() => State.OnUndoAllPauses -= handler);
                            break;

                        case "undoSplit":
                            handler = new EventHandler((object o, EventArgs e) =>
                            {
                                clientConnection.SendMessage(ev);
                            });
                            State.OnUndoSplit += handler;
                            clientConnection.addDisconnectHandler(() => State.OnUndoSplit -= handler);
                            break;
                        }
                    }
                }
                if (message == "startorsplit")
                {
                    if (State.CurrentPhase == TimerPhase.Running)
                    {
                        Model.Split();
                    }
                    else
                    {
                        Model.Start();
                    }
                }
                else if (message == "split")
                {
                    Model.Split();
                }
                else if (message == "unsplit")
                {
                    Model.UndoSplit();
                }
                else if (message == "skipsplit")
                {
                    Model.SkipSplit();
                }
                else if (message == "pause" && State.CurrentPhase != TimerPhase.Paused)
                {
                    Model.Pause();
                }
                else if (message == "resume" && State.CurrentPhase == TimerPhase.Paused)
                {
                    Model.Pause();
                }
                else if (message == "reset")
                {
                    Model.Reset();
                }
                else if (message == "starttimer")
                {
                    Model.Start();
                }
                else if (message.StartsWith("setgametime "))
                {
                    var value = message.Split(' ')[1];
                    var time  = parseTime(value);
                    State.SetGameTime(time);
                }
                else if (message.StartsWith("setloadingtimes "))
                {
                    var value = message.Split(' ')[1];
                    var time  = parseTime(value);
                    State.LoadingTimes = time ?? TimeSpan.Zero;
                }
                else if (message == "pausegametime")
                {
                    State.IsGameTimePaused = true;
                }
                else if (message == "unpausegametime")
                {
                    AlwaysPauseGameTime    = false;
                    State.IsGameTimePaused = false;
                }
                else if (message == "alwayspausegametime")
                {
                    AlwaysPauseGameTime    = true;
                    State.IsGameTimePaused = true;
                }
                else if (message == "getdelta" || message.StartsWith("getdelta "))
                {
                    var comparison = State.CurrentComparison;
                    if (message.Contains(" "))
                    {
                        comparison = message.Split(new char[] { ' ' }, 2)[1];
                    }
                    var delta = LiveSplitStateHelper.GetLastDelta(State, State.CurrentSplitIndex, comparison, State.CurrentTimingMethod);
                    clientConnection.SendMessage(message.Trim(), delta.HasValue ? delta.Value.TotalMilliseconds : 0);
                }
                else if (message == "getsplits")
                {
                    clientConnection.SendMessage(message, State.Run.Select((segment) =>
                    {
                        dynamic result = new System.Dynamic.ExpandoObject();
                        result.icon    = segment.Icon;
                        result.name    = segment.Name;

                        var comparison = segment.Comparisons[State.CurrentComparison][State.CurrentTimingMethod];
                        if (comparison.HasValue)
                        {
                            result.comparison = comparison.Value.TotalMilliseconds;
                        }

                        var splitTime = segment.SplitTime[State.CurrentTimingMethod];
                        if (splitTime.HasValue)
                        {
                            result.splitTime = splitTime.Value.TotalMilliseconds;
                        }

                        var personalBestSplitTime = segment.PersonalBestSplitTime[State.CurrentTimingMethod];
                        if (personalBestSplitTime.HasValue)
                        {
                            result.personalBestSplitTime = personalBestSplitTime.Value.TotalMilliseconds;
                        }

                        var bestSegmentTime = segment.BestSegmentTime[State.CurrentTimingMethod];
                        if (bestSegmentTime.HasValue)
                        {
                            result.bestSegmentTime = bestSegmentTime.Value.TotalMilliseconds;
                        }
                        return(result);
                    }));
                }
                else if (message == "getsplitindex")
                {
                    clientConnection.SendMessage(message, State.CurrentSplitIndex);
                }
                else if (message == "getcurrentsplitname")
                {
                    var splitindex       = State.CurrentSplitIndex;
                    var currentsplitname = State.CurrentSplit.Name;
                    var response         = currentsplitname;
                    clientConnection.SendMessage(message, response);
                }
                else if (message == "getprevioussplitname")
                {
                    var previoussplitindex = State.CurrentSplitIndex - 1;
                    var previoussplitname  = State.Run[previoussplitindex].Name;
                    var response           = previoussplitname;
                    clientConnection.SendMessage(message, response);
                }
                else if (message == "getlastsplittime" && State.CurrentSplitIndex > 0)
                {
                    var splittime = State.Run[State.CurrentSplitIndex - 1].SplitTime[State.CurrentTimingMethod];
                    clientConnection.SendMessage(message, splittime.HasValue ? splittime.Value.TotalMilliseconds : 0);
                }
                else if (message == "getcomparisonsplittime")
                {
                    try
                    {
                        TimeSpan?splittime;
                        if (State.CurrentSplit == null)
                        {
                            splittime = State.Run[0].Comparisons[State.CurrentComparison][State.CurrentTimingMethod];
                        }
                        else
                        {
                            splittime = State.CurrentSplit.Comparisons[State.CurrentComparison][State.CurrentTimingMethod];
                        }

                        var response = 0.0;
                        if (splittime.HasValue)
                        {
                            response = splittime.Value.TotalMilliseconds;
                        }
                        clientConnection.SendMessage(message, response);
                    }
                    catch (Exception e)
                    {
                        clientConnection.SendError(message, e);
                    }
                }
                else if (message == "getcurrenttime")
                {
                    var timingMethod = State.CurrentTimingMethod;
                    if (timingMethod == TimingMethod.GameTime && !State.IsGameTimeInitialized)
                    {
                        timingMethod = TimingMethod.RealTime;
                    }
                    var time = State.CurrentTime[timingMethod];
                    clientConnection.SendMessage(message, time.HasValue ? time.Value.TotalMilliseconds : 0);
                }
                else if (message == "getfinaltime" || message.StartsWith("getfinaltime "))
                {
                    var comparison = State.CurrentComparison;
                    if (message.Contains(" "))
                    {
                        comparison = message.Split(new char[] { ' ' }, 2)[1];
                    }
                    var time = (State.CurrentPhase == TimerPhase.Ended)
                        ? State.CurrentTime[State.CurrentTimingMethod]
                        : State.Run.Last().Comparisons[comparison][State.CurrentTimingMethod];
                    clientConnection.SendMessage(message.Trim(), time.HasValue ? time.Value.TotalMilliseconds : 0);
                }
                else if (message.StartsWith("getpredictedtime "))
                {
                    var comparison = message.Split(new char[] { ' ' }, 2)[1];
                    var prediction = PredictTime(State, comparison);
                    clientConnection.SendMessage(message, prediction.HasValue ? prediction.Value.TotalMilliseconds : 0);
                }
                else if (message == "getbestpossibletime")
                {
                    var comparison = LiveSplit.Model.Comparisons.BestSegmentsComparisonGenerator.ComparisonName;
                    var prediction = PredictTime(State, comparison);
                    clientConnection.SendMessage(message, prediction.HasValue ? prediction.Value.TotalMilliseconds : 0);
                }
                else if (message == "getcurrenttimerphase")
                {
                    var response = State.CurrentPhase.ToString();
                    clientConnection.SendMessage(message, response);
                }
                else if (message == "getcomparison")
                {
                    clientConnection.SendMessage(message, State.CurrentComparison);
                }
                else if (message.StartsWith("setcomparison "))
                {
                    var comparison = message.Split(new char[] { ' ' }, 2)[1];
                    State.CurrentComparison = comparison;
                }
                else if (message == "switchto realtime")
                {
                    State.CurrentTimingMethod = TimingMethod.RealTime;
                }
                else if (message == "switchto gametime")
                {
                    State.CurrentTimingMethod = TimingMethod.GameTime;
                }
                else if (message.StartsWith("setsplitname "))
                {
                    int    index = Convert.ToInt32(message.Split(new char[] { ' ' }, 3)[1]);
                    string title = message.Split(new char[] { ' ' }, 3)[2];
                    State.Run[index].Name = title;
                    State.Run.HasChanged  = true;
                }
                else if (message.StartsWith("setcurrentsplitname "))
                {
                    string title = message.Split(new char[] { ' ' }, 2)[1];
                    State.Run[State.CurrentSplitIndex].Name = title;
                    State.Run.HasChanged = true;
                }
                else if (message == "getGame")
                {
                    dynamic response = new System.Dynamic.ExpandoObject();
                    response.gameName          = State.Run.GameName;
                    response.gameIcon          = State.Run.GameIcon;
                    response.categoryName      = State.Run.CategoryName;
                    response.attempts          = State.Run.AttemptCount;
                    response.completedAttempts = State.Run.AttemptHistory.Where(x => x.Time.RealTime != null).Count();
                    clientConnection.SendMessage(message, response);
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
        public void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode)
        {
            var comparison = Settings.Comparison == "Current Comparison" ? state.CurrentComparison : Settings.Comparison;

            if (!state.Run.Comparisons.Contains(comparison))
            {
                comparison = state.CurrentComparison;
            }
            var comparisonName = CompositeComparisons.GetShortComparisonName(comparison);
            var componentName  = "Previous Segment" + (Settings.Comparison == "Current Comparison" ? "" : " (" + comparisonName + ")");

            InternalComponent.LongestString   = componentName;
            InternalComponent.InformationName = componentName;

            DeltaFormatter.Accuracy     = Settings.DeltaAccuracy;
            DeltaFormatter.DropDecimals = Settings.DropDecimals;
            TimeSaveFormatter.Accuracy  = Settings.TimeSaveAccuracy;

            TimeSpan?timeChange  = null;
            TimeSpan?timeSave    = null;
            var      liveSegment = LiveSplitStateHelper.CheckLiveDelta(state, false, comparison, state.CurrentTimingMethod, false);

            if (state.CurrentPhase != TimerPhase.NotRunning)
            {
                if (liveSegment != null)
                {
                    timeChange = liveSegment;
                    timeSave   = GetPossibleTimeSave(state, state.CurrentSplitIndex, comparison);
                    InternalComponent.InformationName = "Live Segment" + (Settings.Comparison == "Current Comparison" ? "" : " (" + comparisonName + ")");
                }
                else if (state.CurrentSplitIndex > 0)
                {
                    timeChange = LiveSplitStateHelper.GetPreviousSegmentDelta(state, state.CurrentSplitIndex - 1, comparison, state.CurrentTimingMethod);
                    timeSave   = GetPossibleTimeSave(state, state.CurrentSplitIndex - 1, comparison);
                }
                if (timeChange != null)
                {
                    if (liveSegment != null)
                    {
                        InternalComponent.ValueLabel.ForeColor = LiveSplitStateHelper.GetSplitColor(state, timeChange, state.CurrentSplitIndex, false, false, comparison, state.CurrentTimingMethod).Value;
                    }
                    else
                    {
                        InternalComponent.ValueLabel.ForeColor = LiveSplitStateHelper.GetSplitColor(state, timeChange.Value, state.CurrentSplitIndex - 1, false, true, comparison, state.CurrentTimingMethod).Value;
                    }
                }
                else
                {
                    var color = LiveSplitStateHelper.GetSplitColor(state, null, state.CurrentSplitIndex - 1, true, true, comparison, state.CurrentTimingMethod);
                    if (color == null)
                    {
                        color = Settings.OverrideTextColor ? Settings.TextColor : state.LayoutSettings.TextColor;
                    }
                    InternalComponent.ValueLabel.ForeColor = color.Value;
                }
            }
            else
            {
                InternalComponent.ValueLabel.ForeColor = Settings.OverrideTextColor ? Settings.TextColor : state.LayoutSettings.TextColor;
            }

            if (InternalComponent.InformationName != previousNameText)
            {
                InternalComponent.AlternateNameText.Clear();
                if (liveSegment != null)
                {
                    InternalComponent.AlternateNameText.Add("Live Segment");
                    InternalComponent.AlternateNameText.Add("Live Seg.");
                }
                else
                {
                    InternalComponent.AlternateNameText.Add("Previous Segment");
                    InternalComponent.AlternateNameText.Add("Prev. Segment");
                    InternalComponent.AlternateNameText.Add("Prev. Seg.");
                }
                previousNameText = InternalComponent.InformationName;
            }

            InternalComponent.InformationValue = DeltaFormatter.Format(timeChange)
                                                 + (Settings.ShowPossibleTimeSave ? " / " + TimeSaveFormatter.Format(timeSave) : "");

            InternalComponent.Update(invalidator, state, width, height, mode);
        }
예제 #24
0
        public void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode)
        {
            Cache.Restart();

            var timingMethod = state.CurrentTimingMethod;

            if (Settings.TimingMethod == "Real Time")
            {
                timingMethod = TimingMethod.RealTime;
            }
            else if (Settings.TimingMethod == "Game Time")
            {
                timingMethod = TimingMethod.GameTime;
            }

            var timeValue = GetTime(state, timingMethod);

            if (timeValue == null && timingMethod == TimingMethod.GameTime)
            {
                timeValue = GetTime(state, TimingMethod.RealTime);
            }

            if (timeValue != null)
            {
                var timeString = Formatter.Format(timeValue, CurrentTimeFormat);
                int dotIndex   = timeString.IndexOf(".");
                BigTextLabel.Text = timeString.Substring(0, dotIndex);
                if (CurrentAccuracy == TimeAccuracy.Hundredths)
                {
                    SmallTextLabel.Text = timeString.Substring(dotIndex);
                }
                else if (CurrentAccuracy == TimeAccuracy.Tenths)
                {
                    SmallTextLabel.Text = timeString.Substring(dotIndex, 2);
                }
                else
                {
                    SmallTextLabel.Text = "";
                }
            }
            else
            {
                SmallTextLabel.Text = TimeFormatConstants.DASH;
                BigTextLabel.Text   = "";
            }

            if (state.CurrentPhase == TimerPhase.NotRunning || state.CurrentTime[timingMethod] < TimeSpan.Zero)
            {
                TimerColor = state.LayoutSettings.NotRunningColor;
            }
            else if (state.CurrentPhase == TimerPhase.Paused)
            {
                TimerColor = state.LayoutSettings.PausedColor;
            }
            else if (state.CurrentPhase == TimerPhase.Ended)
            {
                if (state.Run.Last().Comparisons[state.CurrentComparison][timingMethod] == null || state.CurrentTime[timingMethod] < state.Run.Last().Comparisons[state.CurrentComparison][timingMethod])
                {
                    TimerColor = state.LayoutSettings.PersonalBestColor;
                }
                else
                {
                    TimerColor = state.LayoutSettings.BehindLosingTimeColor;
                }
            }
            else if (state.CurrentPhase == TimerPhase.Running)
            {
                if (state.CurrentSplit.Comparisons[state.CurrentComparison][timingMethod] != null)
                {
                    TimerColor = LiveSplitStateHelper.GetSplitColor(state, state.CurrentTime[timingMethod] - state.CurrentSplit.Comparisons[state.CurrentComparison][timingMethod],
                                                                    state.CurrentSplitIndex, true, false, state.CurrentComparison, timingMethod)
                                 ?? state.LayoutSettings.AheadGainingTimeColor;
                }
                else
                {
                    TimerColor = state.LayoutSettings.AheadGainingTimeColor;
                }
            }

            if (Settings.OverrideSplitColors)
            {
                BigTextLabel.ForeColor   = Settings.TimerColor;
                SmallTextLabel.ForeColor = Settings.TimerColor;
            }
            else
            {
                BigTextLabel.ForeColor   = TimerColor;
                SmallTextLabel.ForeColor = TimerColor;
            }

            Cache["TimerText"] = BigTextLabel.Text + SmallTextLabel.Text;
            if (BigTextLabel.Brush != null && invalidator != null)
            {
                Cache["TimerColor"] = BigTextLabel.ForeColor.ToArgb();
            }

            if (invalidator != null && Cache.HasChanged)
            {
                invalidator.Invalidate(0, 0, width, height);
            }
        }
예제 #25
0
        void connection_MessageReceived(object sender, MessageEventArgs e)
        {
            if (State == null)
            {
                return;
            }

            try
            {
                var message = e.Message;

                if (message == "split")
                {
                    Model.Split();
                }
                else if (message == "unsplit")
                {
                    Model.UndoSplit();
                }
                else if (message == "skipsplit")
                {
                    Model.SkipSplit();
                }
                else if (message == "pause" && State.CurrentPhase != TimerPhase.Paused)
                {
                    Model.Pause();
                }
                else if (message == "resume" && State.CurrentPhase == TimerPhase.Paused)
                {
                    Model.Pause();
                }
                else if (message == "reset")
                {
                    Model.Reset();
                }
                else if (message == "starttimer")
                {
                    Model.Start();
                }
                else if (message.StartsWith("setgametime "))
                {
                    var value = message.Split(' ')[1];
                    var time  = parseTime(value);
                    State.SetGameTime(time);
                }
                else if (message.StartsWith("setloadingtimes "))
                {
                    var value = message.Split(' ')[1];
                    var time  = parseTime(value);
                    State.LoadingTimes = time ?? TimeSpan.Zero;
                }
                else if (message == "pausegametime")
                {
                    State.IsGameTimePaused = true;
                }
                else if (message == "unpausegametime")
                {
                    State.IsGameTimePaused = false;
                }
                else if (message == "getdelta")
                {
                    var delta    = LiveSplitStateHelper.GetLastDelta(State, State.CurrentSplitIndex, State.CurrentComparison, State.CurrentTimingMethod);
                    var response = DeltaFormatter.Format(delta);
                    e.Connection.SendMessage(response);
                }
                else if (message == "getlastsplittime" && State.CurrentSplitIndex > 0)
                {
                    var splittime = State.Run[State.CurrentSplitIndex - 1].SplitTime[State.CurrentTimingMethod];
                    var response  = SplitTimeFormatter.Format(splittime);
                    e.Connection.SendMessage(response);
                }
                else if (message == "getcomparisonsplittime")
                {
                    var splittime = State.CurrentSplit.Comparisons[State.CurrentComparison][State.CurrentTimingMethod];
                    var response  = SplitTimeFormatter.Format(splittime);
                    e.Connection.SendMessage(response);
                }
                else if (message == "getcurrenttime")
                {
                    var time     = State.CurrentTime[State.CurrentTimingMethod];
                    var response = SplitTimeFormatter.Format(time);
                    e.Connection.SendMessage(response);
                }
                else if (message == "getfinaltime" || message.StartsWith("getfinaltime "))
                {
                    var comparison = State.CurrentComparison;
                    if (message.Contains(" "))
                    {
                        comparison = message.Split(new char[] { ' ' }, 2)[1];
                    }
                    var time = (State.CurrentPhase == TimerPhase.Ended)
                        ? State.CurrentTime[State.CurrentTimingMethod]
                        : State.Run.Last().Comparisons[comparison][State.CurrentTimingMethod];
                    var response = SplitTimeFormatter.Format(time);
                    e.Connection.SendMessage(response);
                }
                else if (message.StartsWith("getpredictedtime "))
                {
                    var comparison = message.Split(new char[] { ' ' }, 2)[1];
                    var prediction = PredictTime(State, comparison);
                    var response   = SplitTimeFormatter.Format(prediction);
                    e.Connection.SendMessage(response);
                }
                else if (message == "getbestpossibletime")
                {
                    var comparison = LiveSplit.Model.Comparisons.BestSegmentsComparisonGenerator.ComparisonName;
                    var prediction = PredictTime(State, comparison);
                    var response   = SplitTimeFormatter.Format(prediction);
                    e.Connection.SendMessage(response);
                }
                else if (message.StartsWith("setcomparison "))
                {
                    var comparison = message.Split(new char[] { ' ' }, 2)[1];
                    State.CurrentComparison = comparison;
                }
                else if (message == "switchto realtime")
                {
                    State.CurrentTimingMethod = TimingMethod.RealTime;
                }
                else if (message == "switchto gametime")
                {
                    State.CurrentTimingMethod = TimingMethod.GameTime;
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
        private void State_OnSplit(object sender, EventArgs e)
        {
            if (State.CurrentPhase == TimerPhase.Ended)
            {
                if ((State.Run.Last().PersonalBestSplitTime[State.CurrentTimingMethod] == null || State.Run.Last().SplitTime[State.CurrentTimingMethod] < State.Run.Last().PersonalBestSplitTime[State.CurrentTimingMethod]) && Settings.PersonalBest)
                {
                    SendPayload("PersonalBest");
                }
                else
                {
                    if (Settings.NotAPersonalBest)
                    {
                        SendPayload("NotAPersonalBest");
                    }
                }
            }
            else
            {
                string payload = null;

                var splitIndex     = State.CurrentSplitIndex - 1;
                var timeDifference = State.Run[splitIndex].SplitTime[State.CurrentTimingMethod] - State.Run[splitIndex].Comparisons[State.CurrentComparison][State.CurrentTimingMethod];

                if (timeDifference != null)
                {
                    if (timeDifference < TimeSpan.Zero)
                    {
                        payload = "SplitAheadGaining";

                        if (LiveSplitStateHelper.GetPreviousSegmentDelta(State, splitIndex, State.CurrentComparison, State.CurrentTimingMethod) > TimeSpan.Zero)
                        {
                            payload = "SplitAheadLosing";
                        }
                    }
                    else
                    {
                        payload = "SplitBehindLosing";

                        if (LiveSplitStateHelper.GetPreviousSegmentDelta(State, splitIndex, State.CurrentComparison, State.CurrentTimingMethod) < TimeSpan.Zero)
                        {
                            payload = "SplitBehindGaining";
                        }
                    }
                }

                //Check for best segment
                TimeSpan?curSegment = LiveSplitStateHelper.GetPreviousSegmentTime(State, splitIndex, State.CurrentTimingMethod);

                if (curSegment != null)
                {
                    if (State.Run[splitIndex].BestSegmentTime[State.CurrentTimingMethod] == null || curSegment < State.Run[splitIndex].BestSegmentTime[State.CurrentTimingMethod])
                    {
                        payload = "BestSegment";
                    }
                }

                if (string.IsNullOrEmpty(payload))
                {
                    payload = "Split";
                }

                SendPayload(payload);
            }
        }
        public void UpdatePresence(LiveSplitState state)
        {
            DeltaFormatter.Accuracy     = Settings.Accuracy;
            DeltaFormatter.DropDecimals = Settings.DropDecimals;

            string GlobalComparison = Settings.Comparison;

            if (GlobalComparison == "Current Comparison")
            {
                GlobalComparison = state.CurrentComparison;
            }

            TimerPhase RunState             = state.CurrentPhase;
            string     CategoryName         = state.Run.CategoryName;
            string     DetailedCategoryName = state.Run.GetExtendedCategoryName();
            string     GameName             = state.Run.GameName;
            string     ShortGameName        = state.Run.GameName.GetAbbreviations().Last();

            TimeSpan?delta = TimeSpan.Zero;

            if (RunState == TimerPhase.NotRunning && Settings.NRClearActivity)
            {
                activityManager.ClearActivity((res) =>
                {
                    if (res != Result.Ok)
                    {
                        throw new ResultException(res);
                    }
                });
                return;
            }

            string RunningImage = "gray_square";
            string SplitName    = "";

            if (RunState == TimerPhase.Running || RunState == TimerPhase.Paused)
            {
                SplitName = state.CurrentSplit.Name;
                // Want to do more with this, maybe more advanced formatting. For now, simple removal.
                if (Settings.SubSplitCount && SplitName.Length > 0)
                {
                    int bracket1 = SplitName.IndexOf("{");
                    int bracket2 = SplitName.IndexOf("}");
                    if (SplitName.Substring(0, 1) == "-")
                    {
                        SplitName = SplitName.Substring(1);
                    }

                    if ((bracket1 != -1 && bracket2 != -1) && SplitName.Length > bracket2)
                    {
                        SplitName = SplitName.Substring(bracket2 + 1);
                    }
                }
            }

            if (RunState != TimerPhase.NotRunning)
            {
                var timestring = "";
                if (state.CurrentSplitIndex > 0)
                {
                    GetDelta(GlobalComparison);
                }

                if (RunState != TimerPhase.Paused && timestring.Length > 0)
                {
                    RunningImage = timestring.Substring(0, 1) == "+" ? "red_square" : "green_square";
                }
            }

            long StartTime = 0;

            if (Settings.DisplayElapsedTimeType == ElapsedTimeType.DisplayAttemptDuration || Settings.DisplayElapsedTimeType == ElapsedTimeType.DisplayADwOffset)
            {
                DateTime sTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

                StartTime = (long)(state.AttemptStarted - sTime).TotalSeconds;

                if (Settings.DisplayElapsedTimeType == ElapsedTimeType.DisplayADwOffset)
                {
                    StartTime -= (long)state.Run.Offset.TotalSeconds;
                }
            }
            else if (Settings.DisplayElapsedTimeType == ElapsedTimeType.DisplayGameTime)
            {
                StartTime = DateTime.UtcNow.Ticks - (long)state.CurrentTime[state.CurrentTimingMethod].Value.TotalSeconds;
            }

            var activity = new Activity
            {
                Details = CheckText("Details"),
                State   = CheckText("State"),
                Assets  =
                {
                    LargeImage = "livesplit_icon",
                    LargeText  = CheckText("largeImage")
                }
            };

            if (Settings.Comparison != NoneComparisonGenerator.ComparisonName)
            {
                activity.Assets.SmallText  = CheckText("smallImage");
                activity.Assets.SmallImage = RunningImage;
            }
            if (RunState == TimerPhase.Running && (int)Settings.DisplayElapsedTimeType >= 1)
            {
                activity.Timestamps.Start = StartTime;
            }

            activityManager.UpdateActivity(activity, (res) =>
            {
                if (res != Result.Ok)
                {
                    throw new ResultException(res);
                }
            });

            string CheckText(string item)
            {
                string text = GetText(item);

                if (text == "%inherit")
                {
                    text = GetText(item, true);

                    if (text.Contains("%delta") || text.Contains("%split"))
                    {
                        if (RunState == TimerPhase.NotRunning)
                        {
                            return("Not Running");
                        }
                        else if (RunState == TimerPhase.Ended)
                        {
                            return("Ended. Final Time: " + TimeFormatter.Format(state.CurrentTime[state.CurrentTimingMethod]));
                        }
                        else if (RunState == TimerPhase.Paused)
                        {
                            return("Paused");
                        }
                        else
                        {
                            text = FindDelta(text);
                            text = text.Replace("%split", SplitName);
                        }
                    }
                }
                else
                {
                    text = FindDelta(text);
                    text = text.Replace("%split", SplitName);
                }

                text = text.Replace("%game_short", ShortGameName);
                text = text.Replace("%game", GameName);
                text = text.Replace("%category_detailed", DetailedCategoryName);
                text = text.Replace("%category", CategoryName);
                text = text.Replace("%attempts", state.Run.AttemptCount.ToString());
                text = text.Replace("%comparison", GlobalComparison);
                text = text.Replace("%time", TimeFormatter.Format(state.CurrentTime[state.CurrentTimingMethod]));

                return(text);
            }

            string GetText(string item, bool GetRunning = false)
            {
                if (RunState == TimerPhase.Running || GetRunning)
                {
                    if (item == "Details")
                    {
                        return(Settings.Details);
                    }

                    else if (item == "State")
                    {
                        return(Settings.State);
                    }

                    else if (item == "largeImage")
                    {
                        return(Settings.largeImageKey);
                    }

                    else
                    {
                        return(Settings.smallImageKey);
                    }
                }

                else if (RunState == TimerPhase.NotRunning)
                {
                    if (item == "Details")
                    {
                        return(Settings.NRDetails);
                    }

                    else if (item == "State")
                    {
                        return(Settings.NRState);
                    }

                    else if (item == "largeImage")
                    {
                        return(Settings.NRlargeImageKey);
                    }

                    else
                    {
                        return(Settings.NRsmallImageKey);
                    }
                }

                else if (RunState == TimerPhase.Ended)
                {
                    if (item == "Details")
                    {
                        return(Settings.EDetails);
                    }

                    else if (item == "State")
                    {
                        return(Settings.EState);
                    }

                    else if (item == "largeImage")
                    {
                        return(Settings.ElargeImageKey);
                    }

                    else
                    {
                        return(Settings.EsmallImageKey);
                    }
                }

                else
                {
                    if (item == "Details")
                    {
                        return(Settings.PDetails);
                    }

                    else if (item == "State")
                    {
                        return(Settings.PState);
                    }

                    else if (item == "largeImage")
                    {
                        return(Settings.PlargeImageKey);
                    }

                    else
                    {
                        return(Settings.PsmallImageKey);
                    }
                }
            }

            string GetDelta(string Comparison)
            {
                int SplitIndex = (RunState == TimerPhase.Ended ? state.CurrentSplitIndex - 1 : state.CurrentSplitIndex);

                delta = LiveSplitStateHelper.GetLastDelta(state, SplitIndex, Comparison, state.CurrentTimingMethod);

                return(DeltaFormatter.Format(delta));
            }

            string FindDelta(string SearchText)
            {
                if (SearchText.IndexOf("%delta_") != -1)
                {
                    SearchText = SearchText.Replace("%delta_cur", GetDelta(state.CurrentComparison));

                    foreach (KeyValuePair <string, string> deltaCheck in ComparisonDict)
                    {
                        SearchText = SearchText.Replace(deltaCheck.Key, GetDelta(deltaCheck.Value));
                    }
                }
                SearchText = SearchText.Replace("%delta", GetDelta(GlobalComparison));
                return(SearchText);
            }
        }