開発環境 Microsoft Visual Studio Express 2013 for Windows Desktop
実行環境 Microsoft Windows 8.1 (64bit)
プロジェクトの種類 Visual C#/コンソール アプリケーション
プロジェクト名 FiddlerMH3

Program.cs
/*
 * プロジェクト/参照
 * ・DynamicJson.dll
 * ・FiddlerCore4.dll
 */
 
using Codeplex.Data;
using Fiddler;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
 
namespace FiddlerMH3
{
    class Program
    {
        static Dictionary<string, string> unit_mst = new Dictionary<string, string>();
        static Dictionary<string, string> equip_mst = new Dictionary<string, string>();
        static string logdir;
        static string map_id;
        static string map_exp;
        static string map_name;
 
        static void Main(string[] args)
        {
            LoadMst(unit_mst, "unit.txt", 2);
            LoadMst(equip_mst, "equip.txt", 1);
 
            logdir = DateTime.Now.ToString("yyyyMMdd_HHmmss");
            Directory.CreateDirectory(logdir);
 
            FiddlerApplication.AfterSessionComplete += FiddlerApplication_AfterSessionComplete;
            Console.CancelKeyPress += Console_CancelKeyPress;
            Disp("Starting {0}...", FiddlerApplication.GetVersionString());
            FiddlerApplication.Startup(0, true, true);
            Disp("Hit CTRL+C to end session.");
 
            try
            {
                bool bDone = false;
                do
                {
                    ConsoleKeyInfo cki = Console.ReadKey();
                    Console.WriteLine();
                    switch (cki.KeyChar)
                    {
                        case 'q':
                            bDone = true;
                            break;
                    }
                } while (!bDone);
            }
            catch (Exception e)
            {
                Disp(e.ToString());
            }
 
            DoQuit();
        }
 
        static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            DoQuit();
        }
 
        private static void DoQuit()
        {
            DispColor(ConsoleColor.Yellow, "Shutting down...");
            FiddlerApplication.Shutdown();
            Thread.Sleep(500);
        }
 
        private static void Disp(string format, params object[] arg)
        {
            DispColor(ConsoleColor.Gray, format, arg);
        }
 
        private static void DispColor(ConsoleColor color, string format, params object[] arg)
        {
            Console.ForegroundColor = color;
            Console.WriteLine(format, arg);
            Console.ResetColor();
        }
 
        private static void LoadMst(Dictionary<string, string> mst, string path, int index)
        {
            using (StreamReader sr = new StreamReader(path, Encoding.Default))
            {
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    string[] cols = line.Split('\t');
                    mst[cols[0]] = cols[index];
                }
            }
        }
 
        private static string GetUnitName(string unit_no)
        {
            return unit_mst.ContainsKey(unit_no) ? unit_mst[unit_no] : unit_no;
        }
 
        private static string GetEquipName(string equip_no)
        {
            return equip_mst.ContainsKey(equip_no) ? equip_mst[equip_no] : equip_no;
        }
 
        static void FiddlerApplication_AfterSessionComplete(Session oSession)
        {
            string[] url = oSession.fullUrl.Split('/');
            if (5 <= url.Length && url[4] == "makeRequest")
            {
                if (oSession.oResponse.MIMEType == "application/json")
                {
                    string req = oSession.GetRequestBodyAsString();
                    string res = oSession.GetResponseBodyAsString();
 
                    string path = string.Format(@"{0}\{1:d8}.log", logdir, oSession.id);
                    using (StreamWriter sw = new StreamWriter(path, false)) // append
                    {
                        sw.WriteLine(oSession.id + "\t" + oSession.fullUrl + "\t" + req + "\t" + res);
                    }
 
                    string jsonstr = res.Substring(res.IndexOf('{'));
                    dynamic json = DynamicJson.Parse(jsonstr);
                    foreach (KeyValuePair<string, dynamic> item in json)
                    {
                        Parse(item.Value, oSession.id);
                    }
                }
            }
        }
 
        private static void Parse(dynamic value, int sid)
        {
            string bodystr = value.body;
            int rc = (int)value.rc;
            dynamic body = DynamicJson.Parse(bodystr);
 
            if (body.IsDefined("command") == false)
            {
                return;
            }
            string cmd = body.command;
            string[][] data;
            {
                string[] rec = body.data.Split('\n');
                data = new string[rec.Length][];
                for (int i = 0; i < rec.Length; i++)
                {
                    data[i] = rec[i].Split(',');
                }
            }
            DispColor(ConsoleColor.DarkGreen, "{0} {1}", sid, cmd);
 
            switch (cmd)
            {
                case "base_data_load":
                    {
                        int r = 0;
                        int num;
                        string[] rec;
                        var unit_list = new Dictionary<long, string[]>();
 
                        //
                        r += 1;
                        num = int.Parse(data[r++][0]);
                        for (int i = 0; i < num; i++)
                        {
                            rec = data[r++];
                            long id = long.Parse(rec[0]);
                            unit_list[id] = rec;
                        }
 
                        //
                        r += 2;
 
                        //
                        r += 1;
                        num = int.Parse(data[r++][0]);
                        for (int i = 0; i < num; i++)
                        {
                            r++;
                        }
 
                        //
                        r += 4;
 
                        //
                        r += 1;
                        num = int.Parse(data[r++][0]);
                        r += num;
 
                        //
                        r += 6;
                        int deck_num = int.Parse(data[r][0]);
                        {
                            int unit_num = int.Parse(data[r][1]);
                            Disp("第{0}部隊:{1}人", 1, unit_num);
                            for (int i = 0; i < unit_num; i++)
                            {
                                long id = long.Parse(data[r][2 + i]);
                                string[] unit = unit_list[id];
                                Disp("{0}) Lv:{3} 士気:{4} no:{2}",
                                    i + 1, id, GetUnitName(unit[3]), unit[6], unit[7]);
                            }
                            r++;
                        }
                        for (int t = 1; t < deck_num; t++)
                        {
                            int unit_num = int.Parse(data[r][0]);
                            Disp("第{0}部隊:{1}人", t + 1, unit_num);
                            for (int i = 0; i < unit_num; i++)
                            {
                                long id = long.Parse(data[r][1 + i]);
                                string[] unit = unit_list[id];
                                Disp("{0}) Lv:{3} 士気:{4} no:{2}",
                                    i + 1, id, GetUnitName(unit[3]), unit[6], unit[7]);
                            }
                            r++;
                        }
                    }
                    break;
 
                case "do_battle":
                    {
                        string[] rec = data[1];
                        int pos = 0;
                        int num;
 
                        //
                        num = int.Parse(rec[pos++]);
                        Disp("射撃回数:{0}", num);
                        for (int i = 0; i < num; i++)
                        {
                            Disp("{11}) ph:{0} ty:{1} sp:{2} {3} so:{4} de:{5} bd:{6} dm:{7} {8} di:{9} dk:{10}",
                                rec[pos + 0], rec[pos + 1], rec[pos + 2], rec[pos + 3],
                                rec[pos + 4], rec[pos + 5], rec[pos + 6], rec[pos + 7],
                                rec[pos + 8], rec[pos + 9], rec[pos + 10], i + 1);
                            pos += 11;
                            /*
                             * 0:0=航空戦 1=制圧射撃 2=砲撃戦 3=追撃戦 4=援護射撃 5=掃討戦
                             * 1:0=白 1=白 2=赤 3=黄 4=青 5=miss
                             * 2:0=通常 1=即応射撃 2=集中射撃 3=掃討戦強化
                             * 4:攻撃元(自0-4 敵1000-1004)
                             * 5:攻撃先
                             * 6:基本ダメージ
                             * 7:実ダメージ
                             * 9:0=自→敵 1=敵→自
                             * 10:部隊番号
                             */
                        }
 
                        // ドロップ
                        string equip_no = (int.Parse(rec[pos + 3]) & 0xffff).ToString();
                        string unit_no = rec[pos + 6];
                        DispColor(ConsoleColor.Cyan, "map:{0} exp:{1} name:{2} eq:{3} un:{4}",
                            map_id, map_exp, map_name, GetEquipName(equip_no), GetUnitName(unit_no));
                        pos += 30;
 
                        //
                        num = int.Parse(rec[pos++]);
                        pos += num;
                        pos += 6;
 
                        //
                        num = int.Parse(rec[pos++]);
                        for (int i = 0; i < num; i++)
                        {
                            int hp_now = int.Parse(rec[pos + 8]);
                            int hp_max = int.Parse(rec[pos + 9]);
                            ConsoleColor color;
                            if (hp_now == hp_max)
                            {
                                color = ConsoleColor.Gray;
                            }
                            else if (hp_max / 4 < hp_now)
                            {
                                color = ConsoleColor.DarkYellow;
                            }
                            else
                            {
                                color = ConsoleColor.Red;
                            }
 
                            DispColor(color,
                                "{0}) Lv:{2} 士気:{3} 体力:{4}/{5} 燃料:{6}/{7} 弾薬:{8}/{9} no:{1}",
                                i + 1, GetUnitName(rec[pos + 2]), rec[pos + 5], rec[pos + 6],
                                hp_now, hp_max,
                                rec[pos + 10], rec[pos + 11], rec[pos + 12], rec[pos + 13]);
                            pos += 26;
                            int n2 = int.Parse(rec[pos++]);
                            for (int j = 0; j < n2; j++)
                            {
                                //Disp("装備{0}:[{1}] {2}", j + 1, rec[pos], GetEquipName(rec[pos]));
                                pos++;
                            }
                            pos += 6;
                        }
 
                        //
                        pos += 101;
 
                        //
                        num = int.Parse(rec[pos++]);
                        pos += num;
 
                        //
                        num = int.Parse(rec[pos++]);
                        if (num != 0)
                        {
                            int unit_num = int.Parse(rec[pos++]);
                            string exp_list = string.Join(",", rec, pos, unit_num);
                            Disp("経験値:{0}", exp_list);
 
                            using (StreamWriter sw = new StreamWriter("drop.log", true)) // append
                            {
                                string[] fld = new string[8];
                                fld[0] = DateTime.Now.ToString("yyyyMMdd_HHmmss");
                                fld[1] = map_id;
                                fld[2] = "";
                                fld[3] = equip_no;
                                fld[4] = unit_no;
                                fld[5] = map_exp;
                                fld[6] = unit_num.ToString();
                                fld[7] = exp_list;
                                sw.WriteLine(string.Join(",", fld));
                            }
                        }
                    }
                    break;
 
                case "get_battle_unit":
                    {
                        int pos = 0;
                        int num;
                        string[] rec;
 
                        pos++;
                        num = int.Parse(data[pos++][0]);
                        pos += num;
 
                        pos += 2;
 
                        pos++;
                        rec = data[pos++];
                        map_id = rec[0];
                        map_exp = rec[2];
                        map_name = rec[4];
                        DispColor(ConsoleColor.Cyan, "map:{0} exp:{1} name:{2}", map_id, map_exp, map_name);
 
                        pos += 3;
                        num = int.Parse(data[pos++][0]);
                        for (int i = 0; i < num; i++)
                        {
                            rec = data[pos++];
                            long id = long.Parse(rec[0]);
                            Disp("{0}) Lv:{2} 士気:{3} 体力:{4}/{5} 燃料:{6}/{7} 弾薬:{8}/{9} no:{1}",
                                i + 1, GetUnitName(rec[2]), rec[5], rec[6],
                                rec[8], rec[9], rec[10], rec[11], rec[12], rec[13]);
                        }
                    }
                    break;
 
                case "update_notice":
                    {
                        Disp("{0}", DateTime.Now.ToString("HH:mm:ss"));
                    }
                    break;
 
                case "user_load":
                    {
                        Disp("{0}", DateTime.Now.ToString("HH:mm:ss"));
                    }
                    break;
            }
        }
    }
}
 

unit.txt
1001	指揮	アイゼンハワー
1002	中戦	エイブラムス
1003	航空	ガブレスキー
1004	中戦	パットン
1005	中戦	プール
1006	対空	ブラッドリー
1007	機歩	マコーリフ
1008	機歩	ギャビン
2001	中戦	オコーナー
2002	中戦	ケイ
2003	中戦	ニコルス
2004	中戦	プロー
2005	中戦	ホロックス
2006	中戦	ヴァンデリュア
2007	指揮	モントゴメリー
3001	航空	ヴィスコンティ
3002	歩兵	カッツァーゴ
3003	中戦	パスクッチ
3004	中戦	ブルーノ
3005	歩兵	リベルエーリ
3006	対空	メッセ
 

equip.txt
1001	Kar98k
1002	M1891/30
1003	M1ガーランド
1004	MP40
1005	StG44
2001	ラハティL-39 対戦車銃
2002	ボーイズ対戦車ライフル
2003	60mmバズーカ M1
2004	PIAT
2005	パンツァーファウスト60
2006	パンツァーシュレック
3001	7.62mm DT28
3002	7.62mm M1919
3003	7.92mm BESA
3004	7.92mm MG34
3005	7.92mm MG42
3006	12.7mm M2
3007	7.92mm MG34+対空銃架
3008	7.92mm MG42+対空銃架
 
最終更新:2015年05月07日 16:17