public void SetData(FFXIVLogDataSet dataset)
        {
            this.ffxivLogDataSet1 = dataset;
            string member = bindingSource1.DataMember;
            bindingSource1.DataSource = dataset;
            bindingSource1.DataMember = member;
            bindingSource2.DataSource = dataset;
            bindingSource2.DataMember = member;

            if (ffxivLogDataSet1.Anaylzed.Count > 0)
            {
                label1.Text = String.Format("{0} - {1}", ffxivLogDataSet1.Anaylzed[0].LocalTime,
                    ffxivLogDataSet1.Anaylzed[ffxivLogDataSet1.Anaylzed.Count - 1].LocalTime.ToString("MM/dd HH:mm:ss"));
            }

            if (dataGridView1.Rows.Count > 0)
            {
                dataGridView1.Rows[0].Selected = true;
            }
            if (dataGridView2.Rows.Count > 0)
            {
                dataGridView2.Rows[dataGridView2.Rows.Count - 1].Selected = true;
            }


            UpdateFilter1();
            UpdateFilter2();
        }
Ejemplo n.º 2
0
        public PivotA(FFXIVLogDataSet.AnaylzedRow[] rows)
        {
            foreach (FFXIVLogDataSet.AnaylzedRow row in rows)
            {
                DataRow newrow = ds.Anaylzed.NewRow();
                newrow.ItemArray = row.ItemArray;
                ds.Anaylzed.AddAnaylzedRow((FFXIVLogDataSet.AnaylzedRow) newrow);
            }

            Tree = new TreeElementA();
            Tree.ds = ds;

            RowLabels = new List<string>();
            Filters = new List<string>();
            Expressions = new List<string>();

            RowLabels.Add("From");
            RowLabels.Add("ActionName");
            RowLabels.Add("To");

            //Expressions.Add("Sum(Numeric)");
            //Expressions.Add("Count(Numeric)");
            //Expressions.Add("Avg(Numeric)");
            //Expressions.Add("Max(Numeric)");
            //Expressions.Add("Min(Numeric)");
            //Expressions.Add("Min(TotalSeconds)");
            //Expressions.Add("Max(TotalSeconds)");

            //めちゃくちゃやねw
            Tree.RowLabels = RowLabels;
            Tree.Expressions = Expressions;
        }
        private void EffectAnalyze(FFXIVLogDataSet.AnaylzedRow arow, FFXIVLog log)
        {
            string _logstring = log.LogBodyReplaceTabCode;
            Regex buffRegex = new Regex(@":  ⇒ (?<to>.+)に「(?<buff>[^」]+)」の(?<on>効果)。|(?<to>[^:\s⇒].+)の「(?<buff>[^」]+)」が(?<off>切れた)。");
            Match match = buffRegex.Match(_logstring);

            if (match.Groups["on"].Value != "")
            {
                arow.IsBuffOn = true;
            }
            else if (match.Groups["off"].Value != "")
            {
                arow.IsDebuffRemove = true;
            }

            arow.To = NameConvertTo(log,match.Groups["to"].Value);
            arow.From = NameConvertFrom(log,match.Groups["from"].Value);
            arow.BuffName = match.Groups["buff"].Value;

            if (arow.From == "")
            {
                SearchAction(arow, log);
            }
            if (arow.IsBuffOn && !arow.IsBuffNameNull())
            {
                FFXIVLogDataSet.ActionRow action = null;
                if (arow.BuffName == "桜花狂咲")
                {
                    action = ds.Action.FindByName("桜華狂咲");
                }
                else
                {
                    action = ds.Action.FindByName(arow.BuffName);
                }
                if (action != null)
                {
                    SetDotSpace(arow);
                }
            }
            if (arow.IsBuffRemove && !arow.IsBuffNameNull())
            {
                FFXIVLogDataSet.ActionRow action = ds.Action.FindByName(arow.BuffName);
                if (action ==null && arow.BuffName == "桜花狂咲")
                {
                    action = ds.Action.FindByName("桜華狂咲");
                }
                if (action != null)
                {
                    CloseDot(arow.To, arow, false);
                }
            }
        }
 private void CureAnalyze(FFXIVLogDataSet.AnaylzedRow arow, FFXIVLog log)
 {
     string _logstring = log.LogBodyReplaceTabCode;
     Regex actionStartRegex = new Regex(@":\s\s⇒\s(|(?<crit>クリティカル!)\s)(?<to>[^!]+)[は](|(?<dodge>[^\d\s]*)\s)(?<num>\d+)(|\((?<bonus>[+-]\d+)\%\))(?<hpmp>\w+)(回復|吸収)");
     Match match = actionStartRegex.Match(_logstring);
     arow.IsCure = true;
     arow.To = NameConvertTo(log,match.Groups["to"].Value);
     arow.From = NameConvertFrom(log,match.Groups["from"].Value);
     arow.ActionName = match.Groups["action"].Value;
     if(match.Groups["num"].Value!="")
     {
         arow.Numeric = Convert.ToInt32(match.Groups["num"].Value, 10);
     }
     if (match.Groups["hpmp"].Value == "HP")
     {
         arow.IsHP = true;
     }
     else if (match.Groups["hpmp"].Value == "TP")
     {
         arow.IsTP = true;
     }
     else if (match.Groups["hpmp"].Value == "MP")
     {
         arow.IsMP = true;
     }
     if (match.Groups["crit"].Value != "")
     {
         arow.IsCritical = true;
     }
     if (arow.From == "")
     {
         if (!log.LogBodyReplaceTabCode.Contains("吸収"))
         {
             SearchAction(arow, log);
         }
         else
         {
         }
     }
 }
        /// <summary>
        /// 倒した倒された力尽きた
        /// </summary>
        /// <param name="arow"></param>
        /// <param name="log"></param>
        private void KOAnaylyze(FFXIVLogDataSet.AnaylzedRow arow, FFXIVLog log)
        {
            string _logstring = log.LogBodyReplaceTabCode;
            Regex koRegex = new Regex(@":(?<to>.+)は、力尽きた。|:(?<to>.+)は、(?<from>.+)に倒された。|:(?<from>.+)は、(?<to>.+)を倒した。");
            Match match = koRegex.Match(_logstring);
            if (match.Success)
            {
                arow.IsKO = true;
                arow.To = NameConvertTo(log, match.Groups["to"].Value);
                arow.From = NameConvertFrom(log, match.Groups["from"].Value);

                FFXIVLogDataSet.EnemyGroupRow eg = ds.EnemyGroup.FindByName(arow.To);
                if (eg != null && (arow.FLAG_WHO == (int)LOG_CATEGORY_WHO.MYSELF || arow.FLAG_WHO == (int)LOG_CATEGORY_WHO.PTMEMBER))
                {
                    eg.KOCount ++;
                    if (eg.KOCount > eg.Count)
                    {
                        eg.Count = eg.KOCount;
                    }
                }
            }
        }
        /// <summary>
        /// コンテンツの開始終了
        /// </summary>
        /// <param name="arow"></param>
        /// <param name="log"></param>
        private void ContentStartEnd(FFXIVLogDataSet.AnaylzedRow arow, FFXIVLog log)
        {
            string _logstring = log.LogBodyReplaceTabCode;
            Regex contentStartRegex = new Regex(@":「(?<content>.+)」の攻略を開始した。");
            Match match = contentStartRegex.Match(_logstring);
            if (match.Success)
            {
                arow.IsContentStart = true;
                arow.ContentName = match.Groups["content"].Value;

                ds.ContentRegion.AddContentRegionRow(arow.ID, -1, arow.ContentName, true, false);

            }
            Regex contentEndRegex = new Regex(@":[^「]*?「(?<content>.+)」の攻略を終了した。");
            match = contentEndRegex.Match(_logstring);
            if (match.Success)
            {
                arow.IsContentEnd = true;
                arow.ContentName = match.Groups["content"].Value;

               FFXIVLogDataSet.ContentRegionRow[]rows= (FFXIVLogDataSet.ContentRegionRow[]) ds.ContentRegion.Select(String.Format("ContentName = '{0}'",arow.ContentName.Replace("'","''")));
               if (rows.Length > 0)
               {
                   rows[rows.Length - 1].EndLogID = arow.ID;
               }
            }

            //:「(?<content>.+)」の攻略を開始した。
        }
        /// <summary>
        /// レベルシンクの開始と終了
        /// </summary>
        /// <param name="arow"></param>
        /// <param name="log"></param>
        private void LevelSyncStartEnd(FFXIVLogDataSet.AnaylzedRow arow, FFXIVLog log)
        {
            string _logstring = log.LogBodyReplaceTabCode;

            Regex LevelSyncRegex = new Regex(@":レベル(?<level>\d+)にシンクされました。");
            Match match = LevelSyncRegex.Match(_logstring);
            if (match.Success)
            {
                arow.SyncLevel = Convert.ToInt32(match.Groups["level"].Value, 10);
                arow.IsLevelSyncStart = true;
            }
            Regex LevelSyncEndRegex = new Regex(@":レベルシンクが解除されました。");
            if (LevelSyncEndRegex.Match(_logstring).Success)
            {
                arow.IsLevelSyncEnd = true;                
            }
        }
        private void CloseDot(string to, FFXIVLogDataSet.AnaylzedRow arow, bool all)
        {
            FFXIVLogDataSet.EnemyGroupRow eg = ds.EnemyGroup.FindByName(to);
            if (eg != null)
            {
                FFXIVLogDataSet.AnaylzedRow[] effectrows = (FFXIVLogDataSet.AnaylzedRow[])ds.Anaylzed.Select(String.Format("ID >= {0} and IsEffecton = true and To = '{1}' and DotEndSeconds is null",
                    eg.FirstID, to.Replace("'", "''")), "ID");

                List<string> effects = new List<string>();

                foreach (FFXIVLogDataSet.AnaylzedRow row in effectrows)
                {//DEBUG
                    if (all)
                    {
                        row.DotEndSeconds = arow.TotalSeconds;
                    }
                    else if (!effects.Contains(row.EffectName))
                    {
                        effects.Add(row.EffectName);
                    }
                    else
                    {
                        row.DotEndSeconds = arow.TotalSeconds;
                    }
                }

            }
        }
 public void SetData(FFXIVLogDataSet ds)
 {
     _dataset = ds;
     bindingSource1.DataSource = _dataset;
     bindingSource1.DataMember = "Anaylzed";
 }
 public FF14LogParser()
 {
     ds = new FFXIVLogDataSet();
     ds.Anaylzed.TableCleared += new DataTableClearEventHandler(Anaylzed_TableCleared);
     SetAction();
 }
        /// <summary>
        /// ダメージ系のアナライズ
        /// </summary>
        /// <param name="arow"></param>
        /// <param name="log"></param>
        private void HitAnalyze(FFXIVLogDataSet.AnaylzedRow arow, FFXIVLog log)
        {
            //敵視UPの場合
            if (log.LogBodyReplaceTabCode.Contains("敵視をアップ"))
            {
                Regex HateRegex = new Regex(@":  ⇒ (?<to>.+)の敵視をアップ。");
                Match match = HateRegex.Match(log.LogBodyReplaceTabCode.Replace("{022705CF01010103}", "").Replace("{0227050101010103}", ""));// System.Diagnostics.Debug.Write(log.LogBody);
                arow.To = NameConvertTo(log,match.Groups["to"].Value);
                arow.IsDamage = true;
                arow.IsHate = true;
                SearchAction(arow, log);
                return;
            }

            else
            {
                Regex HitRegex = new Regex(@":(\s|(?<from>.+)の(?<action>攻撃))\s⇒\s(|(?<crit>クリティカル!)\s)(?<to>[^!]+)[はに](|(?<dodge>[^\d\s]*)\s)(?<dmg>\d+)(|\((?<bonus>[+-]\d+)\%\))ダメージ");

                arow.IsDamage = true;//ダメージタイプである
                arow.IsHP = true;//HPに影響する

                Match match = HitRegex.Match(log.LogBodyReplaceTabCode.Replace("{022705CF01010103}", "").Replace("{0227050101010103}", "")); //System.Diagnostics.Debug.Write(log.LogBody);
                arow.From = NameConvertFrom(log,match.Groups["from"].Value);
                arow.To = NameConvertTo(log,match.Groups["to"].Value);
                arow.ActionName = match.Groups["action"].Value;
                if (match.Groups["dmg"].Value != "")
                {
                    arow.Numeric = Convert.ToInt32(match.Groups["dmg"].Value,10);
                }
                arow.IsCritical = match.Groups["crit"].Value != "";
                if (match.Groups["bonus"].Value != "")
                {
                    arow.BonusRate = Convert.ToInt32(match.Groups["bonus"].Value);
                }
                if (match.Groups["dodge"].Value.Contains("ブロック"))
                {
                    arow.IsBlock = true;
                }
                if (match.Groups["dodge"].Value.Contains("受け流し"))
                {
                    arow.IsParry = true;
                }
            }
            if (arow.From == "")
            {
                SearchAction(arow, log);
            }

            if (arow.IsFromNull()) arow.From = FF14LogParser.UnknownName;
            if (arow.IsActionNameNull()) arow.ActionName = FF14LogParser.UnknownName;

            //int damage = Convert.ToInt32(match.Groups["damage"].Value,10);
            //int bonus = Convert.ToInt32(match.Groups["bonus"].Value,10);
            //string to = match.Groups["to"].Value;
        }
        /// <summary>
        /// 実行した中断したの分析
        /// </summary>
        /// <param name="arow"></param>
        /// <param name="log"></param>
        private void ActionStartDoneAnalyze(FFXIVLogDataSet.AnaylzedRow arow, FFXIVLog log)
        {
            Regex ActionRegex = new Regex(@":(ターゲットが範囲外のため、|)(?<from>[^:\s⇒].+)[はの]「(?<action>[^」]+)」");
            string _logstring = log.LogBodyReplaceTabCode;

            Match match = ActionRegex.Match(_logstring);
            arow.ActionName = match.Groups["action"].Value;

            if (log.LogBodyReplaceTabCode.Contains("中断した"))
            {
                arow.IsInterrupted = true;
            }
            else if (log.LogBodyReplaceTabCode.Contains("中断された"))
            {
                arow.IsInterrupted = true;
            }
            else if (log.LogBodyReplaceTabCode.Contains("の構え") || log.LogBodyReplaceTabCode.Contains("を唱えた"))
            {
                arow.IsStarted = true;
            }
            else
            {
                arow.IsDone = true;
            }

            arow.ActionName= match.Groups["action"].Value;
            arow.From = NameConvertFrom(log,match.Groups["from"].Value);
        }
        /// <summary>
        /// ミス解析
        /// </summary>
        /// <param name="arow"></param>
        /// <param name="log"></param>
        private void DodgeAnalyze(FFXIVLogDataSet.AnaylzedRow arow, FFXIVLog log)
        {
            Regex dodgeRegex = new Regex(@":(\s|(?<from>.+)の(?<action>攻撃))\s⇒\s(?<to>.+)にミス|:  ⇒ (?<to>.+)は「(?<action>[^」]+)」をレジストした。|:  ⇒ (?<to>.+)に効果なし。|:  ⇒ (?<to>.+)はレジストした!");

            arow.IsDodge = true;

            string _logstring = log.LogBodyReplaceTabCode;
            Match match = dodgeRegex.Match(_logstring);

            arow.ActionName = match.Groups["action"].Value;
            arow.To =NameConvertTo(log, match.Groups["to"].Value);
            //System.Diagnostics.Debug.Assert(arow.To != "");
            arow.From =NameConvertFrom(log, match.Groups["from"].Value);

            if (arow.From == "")
            {
                SearchAction(arow, log);
            }
        }
 /// <summary>
 /// データをリセットするか
 /// </summary>
 /// <param name="arow"></param>
 private void CheckReset(FFXIVLogDataSet.AnaylzedRow arow)
 {
     if (ResetID_Box.Checked)
     {
         //インスタンスダンジョン
         if (arow.IsContentStart)
         {
             button1_Click(this, null);
             SetStatus(String.Format("「{0}」が開始されました。DPSをリセットしました。", arow.ContentName));
         }
     }
     if (FFXIVLog.GetLOG_TYPE(arow.ActionType) == LOG_CATEGORY_TYPE.GAME_EVENT)
     {
         if (arow.Body.Contains("封鎖まで") && ResetClose_Box.Checked)
         {
             button1_Click(this, null);
             SetStatus(String.Format("「{0}」 DPSをリセットしました。", arow.Body));
         }
         if (arow.IsLevelSyncStart && ResetLevelSync_Box.Checked)
             button1_Click(this, null);
         if (arow.Body.Contains("チェンジした") && ResetClose_Box.Checked)
         {
             SetStatus(String.Format("「{0}」 DPSをリセットしました。", arow.Body));
             button1_Click(this, null);
         }
     }
 }
        private void SearchAction(FFXIVLogDataSet.AnaylzedRow arow, FFXIVLog log)
        {
            List<string> bodyList = new List<string>();
            bodyList.Add(log.LogBodyReplaceTabCode);

            List<int> parentLogtypes = new List<int>(GetParentActionLogTypes(arow));

            if (parentLogtypes.Count == 0)
            {
                return;
            }

            for (int i = ds.Anaylzed.Count - 2; i >= 0; i--)
            {
                FFXIVLogDataSet.AnaylzedRow ActionRow = ds.Anaylzed[i];
                bodyList.Insert(0, ActionRow.Body);
                int minLogType = (int)log.LogType / 4 * 4;

                if(parentLogtypes.Contains(ActionRow.LogType) && (ActionRow.ActionType == 0xAB || ActionRow.ActionType == 0x2B))
                {
                    arow.ActionName = ds.Anaylzed[i].ActionName;
                    arow.From = ds.Anaylzed[i].From;
                    ActionRow.To = arow.To;
                    break;
                }
                else if (ActionRow.TotalSeconds < log.TotalSeconds - 1)//2秒猶予
                {
                    arow.ActionName = FF14LogParser.UnknownName;
                    arow.From = FF14LogParser.UnknownName;
                    break;
                }
            }
        }
        private void SetDotSpace(FFXIVLogDataSet.AnaylzedRow arow)
        {
            if (!arow.IsEffectOn)
                return ;

            FFXIVLogDataSet.ActionRow action = ds.Action.FindByName(arow.EffectName);
            if (action == null && arow.EffectName == "桜花狂咲")
            {
                action = ds.Action.FindByName("桜華狂咲");
            }

            if (action == null || action.Dot威力 == 0)
            {
                return;//DOT以外は除外
            }

            arow.IsDot = true;
            arow.Dot_Iryoku = action.Dot威力;
            arow.DotSecs = action.効果時間;
            DotRowList.Add(arow);

            if (arow.IsFromNull() || arow.From == "" || arow.From == FF14LogParser.UnknownName)
                return ;
            FFXIVLogDataSet.ActorRow actor = ds.Actor.FindByName(arow.From);
            ////DDダメージを取得
            if (!actor.IsDamageBaseNull())
            {
                arow.DamageBase = actor.DamageBase;
            }
            if (actor.IsNPC || actor.IsOther)
            {
                arow.DotSecs = action.効果時間;//NPC, OTHER はMAXのデフォルトの効果時間
                return ;
            }

           //上書き、効果時間の判定         
            //効果時間内の同じアクション
            FFXIVLogDataSet.AnaylzedRow[] sames = (FFXIVLogDataSet.AnaylzedRow[])ds.Anaylzed.Select(String.Format("ID < {0} and IsEffecton = true and EffectName = '{1}' and To = '{2}' and TotalSeconds > {3} and From = '{4}'",
                arow.ID,
                action.Name,
                arow.To.Replace("'", "''"),
                arow.TotalSeconds - action.効果時間,
                arow.From.Replace("'", "''")));
            if (sames.Length > 0)
            {
                FFXIVLogDataSet.AnaylzedRow[] rows = (FFXIVLogDataSet.AnaylzedRow[])ds.Anaylzed.Select(String.Format("IsKo = false and ToType = 3 and To = '{0}' and EnemyGroupID = {1} and ID >= {2}",
            arow.To, arow.EnemyGroupID,sames[0].ID), "ID");
                FFXIVLogDataSet.AnaylzedRow[] ko_rows = (FFXIVLogDataSet.AnaylzedRow[])ds.Anaylzed.Select(String.Format("IsKo = true and To = '{0}' and EnemyGroupID = {1} and ID > {2}",
                    arow.To, arow.EnemyGroupID, sames[0].ID), "ID");
                arow.DotSpace = sames[0].DotSpace + rows.Length - ko_rows.Length - 1;
                if (arow.DotSpace < 0)
                {
                    arow.DotSpace = 0;
                    sames[sames.Length-1].IsOverride = true;//上書きされた
                    sames[sames.Length-1].DotEndSeconds = arow.TotalSeconds;
                }
            }
            else
            {
                FFXIVLogDataSet.EnemyGroupRow eg = ds.EnemyGroup.FindByName(arow.To);
                if (eg == null)
                {
                    arow.DotSpace = 0;
                    return;
                }
                arow.DotSpace = eg.Count - eg.KOCount - 1;
                if (arow.DotSpace < 0)
                {
                    arow.DotSpace = 0;
                }
                else if (arow.DotSpace > 0)
                {
                }
            }
        }
        /// <summary>
        /// ログタイプから親となるログタイプを推定
        /// </summary>
        /// <param name="logtype"></param>
        /// <returns></returns>
        private int[] GetParentActionLogTypes(FFXIVLogDataSet.AnaylzedRow row)
        {
            int actiontype = row.ActionType;
            int logtype = row.LogType;

            List<int> res = new List<int>();
            
            //効果が切れたが処理できない
            if (row.IsBuffRemove || row.IsDebuffRemove)
            {
                return res.ToArray();
            }

            if (actiontype == 0xA9 || actiontype == 0x29 || actiontype == 0xAA || actiontype == 0xAD || actiontype == 0x2D || actiontype == 0xAF || actiontype == 0x2F || actiontype == 0xAE || actiontype == 0x2E)
            {//攻撃 攻撃 ミス 回復 回復
                if (logtype >= 0x04 && logtype <= 0x07)
                {
                    res.Add(0x04);//自分の発動
                }
                else if (logtype >= 0x08 && logtype <= 0x0B)
                {
                    res.Add(0x08);//PTの発動
                }
                else if (logtype >= 0x0C && logtype <= 0x0F)
                {
                    res.Add(0x0C);//Allyの発動
                }
                else if (logtype >= 0x10 && logtype <= 0x13)
                {
                    res.Add(0x10);//other pcの発動
                }
                else if (logtype >= 0x14 && logtype <= 0x17)
                {
                    res.Add(0x14);//enemyの発動
                }
                else if (logtype >= 0x18 && logtype <= 0x1B)
                {
                    res.Add(0x18);//npcの発動
                }
            }
            return res.ToArray();
        }
        /// <summary>
        /// ログからレポートを作成する
        /// </summary>
        /// <param name="log"></param>
        /// <returns></returns>
        private string CreateReport(FFXIVLogDataSet.AnaylzedRow log)
        {
            //ダメージ
            //if (log.ActionType == 0xA9 || log.ActionType == 0x29)//A9と29があるのはなぜだろう
            //{
            //    if (!log.IsNumericNull())
            //    {

            //        int fromTotal = rep.GetTotalDamage(log.From,0);
            //        int fromtoTotal = rep.GetTotalDamage(log.From,log.To,0);
            //        int toTotal = rep.GetTakenDamage(log.To,0);
            //        double rateFrom = 100.0 *(double)fromtoTotal/(double)fromTotal;
            //        double rateTo = 100.0 *(double)fromtoTotal/(double)toTotal;

            //        return String.Format("{0}[{1}/{3}({2:0.00}%)] ⇒ {4}[{5}/{7}({6:0.00}%)]",
            //            log.From,// 0
            //            fromtoTotal,// 1
            //            rateFrom,// 2
            //            fromTotal,// 3
            //            log.To,// 4
            //            fromtoTotal,//5
            //            rateTo,//6
            //            toTotal);
            //    }
            //}
            return "";
        }