/// <summary>
        /// ログファイルからログを取得する
        /// </summary>
        /// <param name="logfile"></param>
        /// <returns></returns>
        public static FFXIVLog[] GetLogsFromFile(string logfile)
        {

            byte[] buffer = File.ReadAllBytes(logfile);
            MemoryStream ms = new MemoryStream(buffer);

            BinaryReader br = new BinaryReader(ms);

            int lastCount = br.ReadInt32();
            int currentCount = br.ReadInt32();
            int length = currentCount - lastCount;

            FFXIVLog[] logs = new FFXIVLog[length];

            int[] array = new int[length];

            for (int i = 0; i < length; i++)
            {
                array[i] = br.ReadInt32();
            }

            int lastptr =0;

            int j =0;
            foreach (int ptr in array)
            {
                byte[] data = br.ReadBytes(ptr - lastptr);
                logs[j++] = FFXIVLog.ParseSingleLog(data);
                lastptr = ptr;
            }

            return logs;
        }
Example #2
0
        /// <summary>
        /// ログファイルからログを取得する
        /// </summary>
        /// <param name="logfile"></param>
        /// <returns></returns>
        public static FFXIVLog[] GetLogsFromFile(string logfile)
        {
            byte[]       buffer = File.ReadAllBytes(logfile);
            MemoryStream ms     = new MemoryStream(buffer);

            BinaryReader br = new BinaryReader(ms);

            int lastCount    = br.ReadInt32();
            int currentCount = br.ReadInt32();
            int length       = currentCount - lastCount;

            FFXIVLog[] logs = new FFXIVLog[length];

            int[] array = new int[length];

            for (int i = 0; i < length; i++)
            {
                array[i] = br.ReadInt32();
            }

            int lastptr = 0;

            int j = 0;

            foreach (int ptr in array)
            {
                byte[] data = br.ReadBytes(ptr - lastptr);
                logs[j++] = FFXIVLog.ParseSingleLog(data);
                lastptr   = ptr;
            }

            return(logs);
        }
Example #3
0
        /// <summary>
        /// ログを取得する
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static FFXIVLog[] Parse(byte[] data)
        {
            List <FFXIVLog> loglist = new List <FFXIVLog>();

            foreach (byte[] _dat in ParseLogData(data))
            {
                FFXIVLog log = ParseSingleLog(_dat);
                loglist.Add(log);
            }
            return(loglist.ToArray());
        }
Example #4
0
        /// <summary>
        /// 内容からログを生成する
        /// </summary>
        /// <param name="totalseconds"></param>
        /// <param name="logtype"></param>
        /// <param name="actiontype"></param>
        /// <param name="logbody"></param>
        /// <returns></returns>
        public static FFXIVLog CreateLog(int totalseconds, int logtype, int actiontype, string logbody)
        {
            DateTime timestamp = StartDateTime.AddSeconds(totalseconds);

            FFXIVLog log = new FFXIVLog();

            log.TotalSeconds          = totalseconds;
            log.TimstampHexString     = totalseconds.ToString("X").PadLeft(8, '0');
            log.TimeStampServerTime   = timestamp;
            log.LogTypeHexString      = logtype.ToString("X").PadLeft(2, '0') + actiontype.ToString("X").PadLeft(2, '0');
            log.LogBody               = logbody;
            log.LogBodyReplaceTabCode = tabcodeRegex.Replace(log.LogBody, "");
            //log.Raw = data;

            return(log);
        }
        /// <summary>
        /// ログを追加する
        /// </summary>
        /// <param name="log"></param>
        public void AddLog(FFXIVLog log)
        {
            FFXIVLogDataSet.AnaylzedRow arow = ar.Add(log);
            //string myname = rep.GetMyName();
            //if (myname == "")
            //    return;
            //int My_TotalDmg = rep.GetTotalDamage(myname, 0);
            //int My_HitCount = rep.GetHitCount(myname, 0);
            //int My_MissCount = rep.GetMissCount(myname, 0);
            //double My_HitRate = (double)My_HitCount / (double)(My_HitCount + My_MissCount) * 100;
            //double My_Dps = rep.GetTotalDamage(myname, log.TotalSeconds - 60) / 60.0;

            //if (ar.ds.Anaylzed.Count > 2)
            //{
            //    TimeSpan span = (log.TimeStampServerTime - ar.ds.Anaylzed[0].ServerTime);
            //    DateTime viewDateTime = new DateTime(1900, 1, 1, span.Hours, span.Minutes, span.Seconds);
            //    LastTimeLabel.Text = viewDateTime.ToString("HH:mm:ss");
            //}
            //TotalDmgLabel.Text = String.Format("total {0:#,0}", My_TotalDmg);
            //if (My_HitCount + My_MissCount > 0)
            //{
            //    HitLabel.Text = String.Format("hit {0:#,0}/{1:#,0} {2:0.0}%", My_HitCount, My_HitCount + My_MissCount, My_HitRate);
            //}
            //DpsLabel.Text = String.Format("dps {0:0.0}/sec", My_Dps);

            ////ログ形式で表示
            //string a = CreateReport(arow);
            //if (a != "")
            //{
            //    fF14FastReportDataSet.Reportlog.AddReportlogRow(a);
            //    //int cnt = listView1.Height / listView1.Items[0].Bounds.Height +1;
            //    //while (listView1.Items.Count > cnt)
            //    //{
            //    //    listView1.Items.RemoveAt(0);
            //    //}
            //    //int index = Math.Max(0, listView1.Items.Count - cnt);
            //    //listView1.EnsureVisible(listView1.Items.Count-1);
            //    if (!OnMouse)
            //    {
            //        //                    dataGridView1.
            //        dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows.Count - 1;
            //    }
            //}
            Write();
        }
Example #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static FFXIVLog ParseSingleLog(byte[] data)
        {
            string str = GetFF14String(data);

            int      secs      = Convert.ToInt32(str.Substring(0, 8), 16);
            DateTime timestamp = StartDateTime.AddSeconds(secs);

            FFXIVLog log = new FFXIVLog();

            log.TotalSeconds          = secs;
            log.TimstampHexString     = str.Substring(0, 8);
            log.TimeStampServerTime   = timestamp;
            log.LogTypeHexString      = str.Substring(8, 4);
            log.LogBody               = str.Substring(13);
            log.LogBodyReplaceTabCode = tabcodeRegex.Replace(log.LogBody, "");
            log.Raw = data;

            return(log);
        }
Example #7
0
        /// <summary>
        /// ログを反復して読み込みます
        /// </summary>
        private void ReadThread()
        {
            while (Enable)
            {
                try
                {
                    if (ffxivLogMemoryInfo == null)
                    {//ログ位置のサーチから
                        ffxivLogMemoryInfo = FFXIVLogMemoryInfo.Create();
                        continue;
                    }
                    byte[][]   newlogsdata = ffxivLogMemoryInfo.GetNewLogsData();
                    FFXIVLog[] newLogs     = new FFXIVLog[newlogsdata.Length];
                    for (int i = 0; i < newLogs.Length; i++)
                    {
                        newLogs[i] = FFXIVLog.ParseSingleLog(newlogsdata[i]);
                    }

                    LogEventArgs e = new LogEventArgs();
                    e.IsSuccess   = true;
                    e.LogCount    = newLogs.Length;
                    e.NewLogsData = newlogsdata;
                    e.NewLogs     = newLogs;
                    if (LogEvent != null)
                    {
                        LogEvent(this, e);
                    }
                    System.Threading.Thread.Sleep((int)(LogReadIntervalSec * 1000));
                }
                catch
                {
                    LogEventArgs e = new LogEventArgs();
                    e.IsSuccess = false;
                    if (LogEvent != null)
                    {
                        LogEvent(this, e);
                    }
                    System.Threading.Thread.Sleep((int)(RetryIntervalSec * 1000));
                }
            }
        }
        /// <summary>
        /// ペット名なら頭に"MY","PT"等をつける 
        /// </summary>
        /// <param name="baseName"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        private string NameConvertTo(FFXIVLog log, string baseName)
        {

            if (baseName.StartsWith("カーバンクル") ||
                baseName.StartsWith("イフリート・エギ") ||
                baseName.StartsWith("タイタン・エギ") ||
                baseName.StartsWith("ガルーダ・エギ") ||
                baseName.StartsWith("フェアリー・エオス") ||
                baseName.StartsWith("フェアリー・セレネ"))
            {
                if (log.TO == LOG_CATEGORY_TO.EMPTY_OR_ME)
                {
                    return baseName + "(MY)";
                }
                else if (log.TO ==  LOG_CATEGORY_TO.PTMEMBER)
                {
                    return baseName + "(PT)";
                }
                else if (log.TO ==  LOG_CATEGORY_TO.ENEMY)
                {
                    return baseName + "(EN)";
                }
                return baseName + "(OTHER)";
            }
            return baseName;
        }
        /// <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);
            }
        }
        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;
                }
            }
        }
        /// <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="log"></param>
 public void AddLog(FFXIVLog log)
 {
     report.Add(log);
     lastDateTime = log.TimeStampServerTime.ToLocalTime();
     if (ViewLog)
     {
         LogTextLabel.Text = String.Format("[{0}]{1}", log.TimeStampServerTime.AddHours(9.0).ToString("HH:mm:ss"), log.LogBodyReplaceTabCode);
     }
     else if(LogTextLabel.Text !="")
     {
         LogTextLabel.Text = "";
     }
 }
Example #15
0
 /// <summary>
 /// タブコードをエスケープしたデータを取得します。
 /// </summary>
 /// <returns></returns>
 public byte[] EscapeTabcode()
 {
     return(FFXIVLog.EscapeTabData(Raw));
 }
        /// <summary>
        /// 表示するログか
        /// </summary>
        /// <param name="log"></param>
        /// <returns></returns>
        private bool IsVisibleLog(FFXIVLog log)
        {
            if (log.LogTypeHexString == "0018" && FCBox.Checked)//fc
            {
                return true;
            }
            else if (log.LogTypeHexString == "000B" && ShoutBox.Checked)//shout
            {
                return true;
            }
            else if (log.LogTypeHexString == "000C" && YellBox.Checked)//yell
            {
                return true;
            }
            else if (log.LogTypeHexString == "000E" && PartyBox.Checked)//Party
            {
                return true;
            }
            else if (log.LogTypeHexString == "000B" && ShoutBox.Checked)//shout
            {
                return true;
            }
            else if (log.LogTypeHexString == "0010" && LS1Box.Checked) //LS1
            {
                return true;
            }
            else if (log.LogTypeHexString == "0011" && LS2Box.Checked) //LS2
            {
                return true;
            }
            else if (log.LogTypeHexString == "0012" && LS3Box.Checked) //LS3
            {
                return true;
            }
            else if (log.LogTypeHexString == "0013" && LS4Box.Checked) //LS4
            {
                return true;
            }
            else if (log.LogTypeHexString == "0014" && LS5Box.Checked) //LS5
            {
                return true;
            }
            else if (log.LogTypeHexString == "0015" && LS6Box.Checked) //LS6
            {
                return true;
            }
            else if (log.LogTypeHexString == "0016" && LS7Box.Checked) //LS7
            {
                return true;
            }
            else if (log.LogTypeHexString == "0017" && LS8Box.Checked) //LS8
            {
                return true;
            }
            return false;

        }
        /// <summary>
        /// 内容からログを生成する
        /// </summary>
        /// <param name="totalseconds"></param>
        /// <param name="logtype"></param>
        /// <param name="actiontype"></param>
        /// <param name="logbody"></param>
        /// <returns></returns>
        public static FFXIVLog CreateLog(int totalseconds,int logtype, int actiontype,string logbody)
        {
            DateTime timestamp = StartDateTime.AddSeconds(totalseconds);

            FFXIVLog log = new FFXIVLog();
            log.TotalSeconds = totalseconds;
            log.TimstampHexString = totalseconds.ToString("X").PadLeft(8,'0');
            log.TimeStampServerTime = timestamp;
            log.LogTypeHexString = logtype.ToString("X").PadLeft(2, '0') + actiontype.ToString("X").PadLeft(2, '0');
            log.LogBody = logbody;
            log.LogBodyReplaceTabCode = tabcodeRegex.Replace(log.LogBody, "");
            //log.Raw = data;

            return log;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static FFXIVLog ParseSingleLog(byte[] data)
        {
            string str = GetFF14String(data);

            int secs = Convert.ToInt32(str.Substring(0, 8),16);
            DateTime timestamp = StartDateTime.AddSeconds(secs);

            FFXIVLog log = new FFXIVLog();
            log.TotalSeconds = secs;
            log.TimstampHexString = str.Substring(0, 8);
            log.TimeStampServerTime = timestamp;
            log.LogTypeHexString = str.Substring(8, 4);
            log.LogBody = str.Substring(13);
            log.LogBodyReplaceTabCode = tabcodeRegex.Replace(log.LogBody, "");
            log.Raw = data;

            return log;
        }
        /// <summary>
        /// ログの種類からログカラーを取得します
        /// </summary>
        /// <param name="log"></param>
        /// <returns></returns>
        private Color GetColorFromLog(FFXIVLog log)
        {
            if (log.LogTypeHexString == "0018")//fc
            {
                return Color.LightGreen;
            }
            else if (log.LogTypeHexString =="000B")//shout
            {
                return Color.DarkOrange;
            }
            else if (log.LogTypeHexString == "000C")//yell
            {
                return Color.Orange;
            }
            else if (log.LogTypeHexString == "000E")//Party
            {
                return Color.LightSeaGreen;
            }
            else if (log.LogTypeHexString == "0010" || //LS
                log.LogTypeHexString == "0011" ||
                log.LogTypeHexString == "0012" ||
                log.LogTypeHexString == "0013" ||
                log.LogTypeHexString == "0014" ||
                log.LogTypeHexString == "0015" ||
                log.LogTypeHexString == "0016" ||
                log.LogTypeHexString == "0017")
            {
                return Color.Green;
            }
            //デフォルトはホワイトスモーク
            return Color.WhiteSmoke;

        }
        /// <summary>
        /// ログを追加する
        /// </summary>d
        /// <param name="log"></param>
        /// <returns></returns>
        public FFXIVLogDataSet.AnaylzedRow Add(FFXIVLog log)
        {
            FFXIVLogDataSet.AnaylzedRow arow = ds.Anaylzed.NewAnaylzedRow();
            arow.Body = log.LogBodyReplaceTabCode;

            arow.TotalSeconds = log.TotalSeconds;
            arow.ServerTime = log.TimeStampServerTime;
            arow.LocalTime = log.TimeStampServerTime.AddHours(9);
            arow.ActionType = log.ActionType;
            arow.LogType = log.LogType;

            arow.FLAG_WHO = log.LogType / 4;
            arow.FLAG_TO = log.LogType & 3;
            arow.FLAG_FIGHT = log.ActionType / 128;
            arow.FLAG_INFO = log.ActionType / 16;
            arow.FLAG_UNKNOWN = log.ActionType / 4;
            arow.FLAG_NUM = log.ActionType & 7;


            ds.Anaylzed.AddAnaylzedRow(arow);

            if (log.WHO != LOG_CATEGORY_WHO.SYSTEM && log.LOG_TYPE == LOG_CATEGORY_TYPE.BATTLE)
            {
                if (log.BATTLE_TYPE == LOG_BATTLE_TYPE.HIT)// log.ActionType == 0xA9 || log.ActionType == 0x29)//A9と29があるのはなぜだろう
                {
                    HitAnalyze(arow, log);
                }
                else if (log.BATTLE_TYPE == LOG_BATTLE_TYPE.DONE)// log.ActionType == 0x2B||log.ActionType == 0xAB)
                {
                    ActionStartDoneAnalyze(arow, log);
                }
                else if (log.BATTLE_TYPE == LOG_BATTLE_TYPE.MISS)// log.ActionType == 0xAA||log.ActionType==0x2A)//AAと2Aがある
                {
                    DodgeAnalyze(arow, log);
                }
                else if (log.BATTLE_TYPE == LOG_BATTLE_TYPE.EFFECT1 || log.BATTLE_TYPE == LOG_BATTLE_TYPE.EFFECT2)// log.ActionType == 0xAE || log.ActionType == 0x2E)//ON OFFが表示される効果
                {
                    EffectAnalyze(arow, log);
                }
                else if (log.BATTLE_TYPE == LOG_BATTLE_TYPE.HEAL)//log.ActionType == 0xAD || log.ActionType == 0x2D)
                {
                    CureAnalyze(arow, log);
                }
            }
            else if (log.LOG_TYPE == LOG_CATEGORY_TYPE.GAME_EVENT)
            {
                if (log.GAME_EVENT_TYPE == LOG_GAME_EVENT_TYPE.DOWN_KO)//log.ActionType == 0xBA || log.ActionType == 0x3A)
                {//倒されたとき
                    KOAnaylyze(arow, log);
                    if (arow.IsKO)
                    {
                        CloseDot(arow.To, arow, false);//ひとつ閉じる
                        FFXIVLogDataSet.ActorRow acrow = ds.Actor.FindByName(arow.To);
                        if (acrow != null)
                        {
                            arow.EnemyGroupID = acrow.GroupCount;
                        }
                    }
                }
                else if (log.GAME_EVENT_TYPE == LOG_GAME_EVENT_TYPE.EVENT)// log.ActionType == 0x39)
                {//コンテンツの開始等
                    ContentStartEnd(arow, log);
                    LevelSyncStartEnd(arow, log);
                    if (log.LogBodyReplaceTabCode.Contains("チェンジ"))
                    {//ジョブチェンジ
                        Regex regex = new Regex(@":(?<name>[A-Z][a-z']+? [A-Z][a-z']+?)は「(?<jobclass>\w+?)」にチェンジした。");// :Choco Ponは「白魔道士」にチェンジした。
                        Match match = regex.Match(log.LogBodyReplaceTabCode);
                        if (match.Success)
                        {
                            string name = match.Groups["name"].Value;
                            string jobclass = match.Groups["jobclass"].Value;
                            FFXIVLogDataSet.ActorRow actor = ds.Actor.FindByName(name);
                            if (actor != null)
                            {
                                actor.ClassJob = jobclass;
                            }
                        }
                    }
                }
            }

            //TO と FROM
            FFXIVLogDataSet.ActorRow acrow_from = null;
            FFXIVLogDataSet.ActorRow acrow_to = null;


            if (!arow.IsToNull() && arow.To != "" && arow.To != FF14LogParser.UnknownName)
            {//Toに名前が入っていれば
                acrow_to = ds.Actor.FindByName(arow.To);
                bool need = false;
                if (acrow_to == null)
                {
                    need = true;
                    acrow_to = ds.Actor.NewActorRow();
                    acrow_to.Name = arow.To;
                    acrow_to.FirstLogID = arow.ID;
                    acrow_to.LastLogID = arow.ID;
                    acrow_to.LastSeconds = arow.TotalSeconds;
                    acrow_to.GroupCount = 1;
                    ds.Actor.AddActorRow(acrow_to);
                }
                else
                {
                    need = false;
                    if (arow.TotalSeconds - acrow_to.LastSeconds > 60)
                    {//最後にみてから60秒以上経過していれば、更新する
                        //DOT閉じる
                        CloseDot(arow.To, arow, true);
                        acrow_to.GroupCount++;//名前が同じだが、別グループである
                        need = true;
                    }
                    acrow_to.LastLogID = arow.ID;
                    acrow_to.LastSeconds = arow.TotalSeconds;
                    arow.EnemyGroupID = acrow_to.GroupCount;

                }

                //Toのカテゴリわけ
                //Actorを更新する
                if (need)// FFXIVLog.GetBATTLE_TYPE(arow.ac (arow.ActionType == 0x2B || arow.ActionType == 0xAB))
                {
                    acrow_to.IsMe = false;
                    acrow_to.IsMyPet = false;
                    acrow_to.IsPTMember = false;
                    acrow_to.IsPTPet = false;
                    acrow_to.IsNPC = false;
                    acrow_to.IsAllianceMember = false;

                    if (arow.FLAG_TO == (int)LOG_CATEGORY_TO.EMPTY_OR_ME)
                    {//ME
                        int ptype = GetPlayerTypeFromName(acrow_to.Name);
                        if (ptype == 0)
                        {
                            acrow_to.IsMe = true;
                        }
                        else if (ptype == 1)
                        {
                            acrow_to.IsMyPet = true;
                        }
                        else
                        {
                            acrow_to.IsNPC = true;
                        }
                    }
                    else if (arow.FLAG_TO == (int)LOG_CATEGORY_TO.PTMEMBER)
                    {//PT
                        int ptype = GetPlayerTypeFromName(acrow_to.Name);
                        if (ptype == 0)
                        {
                            acrow_to.IsPTMember = true;
                        }
                        else if (ptype == 1)
                        {
                            acrow_to.IsPTPet = true;
                        }
                        else
                        {
                            acrow_to.IsNPC = true;
                        }
                    }
                    else if (arow.FLAG_TO == (int)LOG_CATEGORY_TO.ENEMY)
                    {
                        int ptype = GetPlayerTypeFromName(acrow_to.Name);
                        if (ptype == 0)
                        {
                            acrow_to.IsOther = true;
                        }
                        else if (ptype == 1)
                        {
                            acrow_to.IsOther = true;
                        }
                        else
                        {
                            acrow_to.IsNPC = true;
                        }
                    }
                    else if (arow.FLAG_TO == (int)LOG_CATEGORY_TO.OTHER)
                    {
                        int ptype = GetPlayerTypeFromName(acrow_to.Name);
                        if (ptype == 0 || ptype == 1)
                        {
                            acrow_to.IsOther = true;
                        }
                        else
                        {
                            acrow_to.IsNPC = true;
                        }
                    }
                    else
                    {
                    }
                }

            }//TOの処理END

            if (!arow.IsFromNull() && arow.From != "" && arow.From != FF14LogParser.UnknownName)
            {//Fromに名前が入っていれば
                //bool need = false;
                acrow_from = ds.Actor.FindByName(arow.From);
                if (acrow_from == null)
                {
                    // need = true;
                    acrow_from = ds.Actor.NewActorRow();
                    acrow_from.Name = arow.From;
                    acrow_from.FirstLogID = arow.ID;
                    acrow_from.LastLogID = arow.ID;
                    acrow_from.LastSeconds = arow.TotalSeconds;
                    acrow_from.GroupCount = 1;
                    ds.Actor.AddActorRow(acrow_from);
                }
                else
                {
                    // need = false;
                    if (arow.TotalSeconds - acrow_from.LastSeconds > 60)
                    {//最後にみてから60秒以上経過していれば、更新する
                        //DOT閉じる
                        CloseDot(arow.From, arow, true);
                        acrow_from.GroupCount++;//名前が同じだが、別グループである
                        // need = true;
                    }
                    acrow_from.LastLogID = arow.ID;
                    acrow_from.LastSeconds = arow.TotalSeconds;
                    arow.EnemyGroupID = acrow_from.GroupCount;

                }
                //DOTのDamageBaseを設定する
                FFXIVLogDataSet.ActionRow action = null;
                if (!arow.IsNumericNull() && arow.ActionName != "攻撃")
                {
                    action = ds.Action.FindByName(arow.ActionName);
                    if (action != null && action.DD威力 > 0)
                    {
                        if (action.Name != "サンダガ" 
                            && action.Name != "ファイア" 
                            && action.Name != "ファイラ" 
                            && action.Name != "ファイガ" 
                            && action.Name != "フレア"
                            && action.Name !="インパルスドライブ")
                        {
                            double bai = 1.0;
                            if (arow.IsCritical)
                            {
                                bai = 1.5;
                            }
                            if (arow.BonusRate > 0)
                            {
                                bai = (100 + arow.BonusRate) / 100.0;
                            }
                            acrow_from.DamageBase = (double)arow.Numeric / bai / action.DD威力;
                        }
                    }
                }
                //Actorを更新する
                if (true)//(need)// FFXIVLog.GetBATTLE_TYPE(arow.ac (arow.ActionType == 0x2B || arow.ActionType == 0xAB))
                {
                    acrow_from.IsMe = false;
                    acrow_from.IsMyPet = false;
                    acrow_from.IsPTMember = false;
                    acrow_from.IsPTPet = false;
                    acrow_from.IsNPC = false;
                    acrow_from.IsAllianceMember = false;

                    if (arow.LogType >= 0x04 && arow.LogType <= 0x07)
                    {//ME
                        int ptype = GetPlayerTypeFromName(acrow_from.Name);
                        if (ptype == 0)
                        {
                            acrow_from.IsMe = true;
                        }
                        else if (ptype == 1)
                        {
                            acrow_from.IsMyPet = true;
                        }
                        else
                        {
                            acrow_from.IsNPC = true;
                        }
                    }
                    else if (arow.LogType >= 0x08 && arow.LogType <= 0x0B)
                    {//PT
                        int ptype = GetPlayerTypeFromName(acrow_from.Name);
                        if (ptype == 0)
                        {
                            acrow_from.IsPTMember = true;
                        }
                        else if (ptype == 1)
                        {
                            acrow_from.IsPTPet = true;
                        }
                        else
                        {
                            acrow_from.IsNPC = true;
                        }
                    }
                    else if (arow.LogType >= 0x0C && arow.LogType <= 0x0F)
                    {//Ally
                        int ptype = GetPlayerTypeFromName(acrow_from.Name);
                        if (ptype == 0 || ptype == 1)
                        {
                            acrow_from.IsAllianceMember = true;
                        }
                        else
                        {
                        }
                    }
                    else if (arow.LogType >= 0x10 && arow.LogType <= 0x13)
                    {
                        int ptype = GetPlayerTypeFromName(acrow_from.Name);
                        if (ptype == 0)
                        {
                            acrow_from.IsOther = true;
                        }
                        else if (ptype == 1)
                        {
                            acrow_from.IsOther = true;
                        }
                        else
                        {
                        }
                    }
                    else if (arow.LogType >= 0x14)
                    {
                        int ptype = GetPlayerTypeFromName(acrow_from.Name);
                        if (ptype == 0 || ptype == 1)
                        {
                            acrow_from.IsOther = true;
                        }
                        else
                        {
                            acrow_from.IsNPC = true;
                        }
                    }
                    else
                    {
                    }
                    if (action != null && (acrow_from.IsMe || acrow_from.IsPTMember || acrow_from.IsOther))
                    {//クラス・ジョブの設定
                        if (acrow_from.IsClassJobNull())
                        {
                            acrow_from.ClassJob = action.Class;
                        }
                        else
                        {
                            List<string> classes = new List<string>(action.Class.Split(new char[] { ' ' }));
                            List<string> forecast_classes = new List<string>(acrow_from.ClassJob.Split(new char[] { ' ' }));
                            List<string> new_classes = new List<string>();
                            foreach (string cls in forecast_classes)
                            {
                                if (classes.Contains(cls))
                                {
                                    new_classes.Add(cls);
                                }
                            }
                            if (new_classes.Count > 0)
                            {
                                acrow_from.ClassJob = String.Join(" ", new_classes.ToArray());
                            }
                            else
                            {
                                acrow_from.ClassJob = action.Class;
                            }
                        }
                    }


                }

            }
            //if ((acrow_from!=null&&acrow_from.Name.Contains("カーバンクル")) && (acrow_to!=null && acrow_to.Name == "オチュー"))
            //{
            //}
            //FROMの処理END
            //EnemyGroup処理 自分・味方から⇒敵に攻撃
            if (((acrow_from != null && acrow_from.Name != FF14LogParser.UnknownName) && (acrow_to != null && acrow_to.Name != FF14LogParser.UnknownName)) && (acrow_from.IsMe || acrow_from.IsMyPet || acrow_from.IsPTMember || acrow_from.IsPTPet))
            {
                if (!arow.IsActionNameNull())
                {
                    FFXIVLogDataSet.ActionRow action = ds.Action.FindByName(arow.ActionName);
                    if ((action != null && action.IsAttack && !arow.IsCure) || arow.ActionName == "攻撃")
                    {
                        FFXIVLogDataSet.EnemyGroupRow eg = ds.EnemyGroup.FindByName(acrow_to.Name);
                        if (eg == null)
                        {
                            eg = ds.EnemyGroup.NewEnemyGroupRow();
                            eg.Name = acrow_to.Name;
                            eg.FirstID = arow.ID;
                            eg.FirstSeconds = arow.TotalSeconds;
                            eg.LastID = arow.ID;
                            eg.LastSeconds = arow.TotalSeconds;
                            eg.KOCount = 0;
                            eg.Count = 1;
                            ds.EnemyGroup.AddEnemyGroupRow(eg);
                        }
                        else
                        {
                            if (eg.LastSeconds < arow.TotalSeconds - 60)
                            {
                                //Dotを閉じる
                                CloseDot(eg.Name, arow, true);

                                eg.FirstID = arow.ID;
                                eg.FirstSeconds = arow.TotalSeconds;
                                eg.LastID = arow.ID;
                                eg.LastSeconds = arow.TotalSeconds;
                                eg.KOCount = 0;
                                eg.Count = 1;

                            }
                            else if (arow.FLAG_TO == (int)LOG_CATEGORY_TO.OTHER)
                            {
                                eg.LastID = arow.ID;
                                eg.LastSeconds = arow.TotalSeconds;
                                eg.Count++;
                            }
                            else
                            {
                                eg.LastID = arow.ID;
                                eg.LastSeconds = arow.TotalSeconds;
                            }

                        }
                    }
                }
            }
            //EnemyGroup処理 敵⇒自分味方への攻撃
            if (((acrow_from != null && acrow_from.Name != FF14LogParser.UnknownName) && (acrow_to != null && acrow_to.Name != FF14LogParser.UnknownName)) && (acrow_to.IsMe || acrow_to.IsMyPet || acrow_to.IsPTMember || acrow_to.IsPTPet))
            {
                if (arow.FLAG_WHO == (int)LOG_CATEGORY_WHO.NPC)
                {
                    FFXIVLogDataSet.EnemyGroupRow eg = ds.EnemyGroup.FindByName(acrow_from.Name);
                    if (eg == null)
                    {
                        eg = ds.EnemyGroup.NewEnemyGroupRow();
                        eg.Name = acrow_from.Name;
                        eg.FirstID = arow.ID;
                        eg.FirstSeconds = arow.TotalSeconds;
                        eg.LastID = arow.ID;
                        eg.LastSeconds = arow.TotalSeconds;
                        eg.KOCount = 0;
                        eg.Count = 1;
                        ds.EnemyGroup.AddEnemyGroupRow(eg);
                    }
                    else
                    {
                        if (eg.LastSeconds < arow.TotalSeconds - 60)
                        {
                            //Dotを閉じる
                            CloseDot(eg.Name, arow, true);

                            eg.FirstID = arow.ID;
                            eg.FirstSeconds = arow.TotalSeconds;
                            eg.LastID = arow.ID;
                            eg.LastSeconds = arow.TotalSeconds;
                            eg.KOCount = 0;
                            eg.Count = 1;
                        }
                        else if (arow.FLAG_WHO == (int)LOG_CATEGORY_WHO.NPC)
                        {
                            eg.LastID = arow.ID;
                            eg.LastSeconds = arow.TotalSeconds;
                            eg.Count++;
                        }
                        else
                        {
                            eg.LastID = arow.ID;
                            eg.LastSeconds = arow.TotalSeconds;
                        }

                    }
                }
            }

            //DOTをとじる
            for (int i = DotRowList.Count-1; i >=0 ; i--)
            {
                if ( DotRowList[i].IsDamageBaseNull() || DotRowList[i].DamageBase==0)
                {
                    FFXIVLogDataSet.ActorRow actor = ds.Actor.FindByName(DotRowList[i].From);
                    if (actor != null &&!actor.IsDamageBaseNull()&& actor.DamageBase>0)
                    {
                        DotRowList[i].DamageBase = actor.DamageBase;
                    }
                }
                else if (DotRowList[i].TotalSeconds + DotRowList[i].DotSecs <=arow.TotalSeconds)
                {
                    DotRowList[i].DotEndSeconds = DotRowList[i].TotalSeconds + DotRowList[i].DotSecs;
                    DotRowList.Remove(DotRowList[i]);
                }
            }

            return arow;

        }
 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 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;                
            }
        }
        /// <summary>
        /// ログを追加する
        /// </summary>
        /// <param name="log"></param>
        public void Add(FFXIVLog log)
        {
            FFXIVLogDataSet.AnaylzedRow arow = ar.Add(log);

        }
        /// <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="log"></param>
 private void LogAdded(FFXIVLog log)
 {
     rf.AddLog(log);
     //arf.AddLog(log);
 }
        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);
                }
            }
        }
Example #27
0
 /// <summary>
 /// ゲーム画面で表示される形に近いStringを取得する
 /// </summary>
 /// <param name="data"></param>
 /// <returns></returns>
 public static string GetFF14String(byte[] data)
 {
     byte[] a    = new byte[] { 0xEE, 0x81, 0xAF };//EE81AFは3バイトの特殊文字 リプレースすることで表示可能
     byte[] buff = FFXIVLog.EscapeTabData(data);
     return(Encoding.GetEncoding("utf-8").GetString(buff).Replace(Encoding.GetEncoding("utf-8").GetString(a), "⇒"));
 }
        /// <summary>
        /// ログを反復して読み込みます
        /// </summary>
        private void ReadThread()
        {
            while (Enable)
            {
                try
                {
                    if (ffxivLogMemoryInfo == null)
                    {//ログ位置のサーチから
                        ffxivLogMemoryInfo = FFXIVLogMemoryInfo.Create();
                        continue;
                    }
                    byte[][] newlogsdata = ffxivLogMemoryInfo.GetNewLogsData();
                    FFXIVLog[] newLogs = new FFXIVLog[newlogsdata.Length];
                    for (int i = 0; i < newLogs.Length; i++)
                    {
                        newLogs[i] = FFXIVLog.ParseSingleLog(newlogsdata[i]);
                    }

                    LogEventArgs e = new LogEventArgs();
                    e.IsSuccess = true;
                    e.LogCount = newLogs.Length;
                    e.NewLogsData = newlogsdata;
                    e.NewLogs = newLogs;
                    if (LogEvent != null)
                    {
                        LogEvent(this, e);
                    }
                    System.Threading.Thread.Sleep((int)(LogReadIntervalSec * 1000));
                }
                catch
                {
                    LogEventArgs e = new LogEventArgs();
                    e.IsSuccess = false;
                    if (LogEvent != null)
                    {
                        LogEvent(this, e);
                    }
                    System.Threading.Thread.Sleep((int)(RetryIntervalSec * 1000));
                }
            }
        }
        /// <summary>
        /// ログを1行追加する
        /// </summary>
        /// <param name="log"></param>
        private void AddLog(FFXIVLog log)
        {
            LogBodyBox.SelectionColor = GetColorFromLog(log);
            Font baseFont = LogBodyBox.SelectionFont;
            Font fnt = new Font(baseFont.FontFamily,
                baseFont.Size,
                baseFont.Style | FontStyle.Bold);

            //Fontを変更する
            LogBodyBox.SelectionFont = fnt;
            //文字列を挿入する
            LogBodyBox.SelectedText = String.Format("[{0}]{1}:{2}\r\n", log.TimeStampServerTime.ToString("MM/dd HH:mm:ss"), log.LogTypeHexString, log.LogBodyReplaceTabCode);

            baseFont.Dispose();
            fnt.Dispose();

        }