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

Program.cs
/*
 * プロジェクト参照
 * ・アセンブリ/フレームワーク
 *  ・System.Web
 * ・参照
 *  ・DynamicJson.dll
 */
 
using Codeplex.Data;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
 
namespace kcsapiTest2
{
    class Program
    {
        static readonly string[] formation = { null, "単縦陣", "複縦陣", "輪形陣", "梯形陣", "単横陣" };
        static readonly string[] intercept = { null, "同航戦", "反航戦", "T字戦(有利)", "T字戦(不利)" };
 
        static dynamic api_deck;    // 艦隊
        static Dictionary<int, dynamic> mst_ship = new Dictionary<int, dynamic>();    // 艦マスタ
        static Dictionary<int, dynamic> mst_slot = new Dictionary<int, dynamic>();    // 装備マスタ
        static Dictionary<int, dynamic> lst_ship = new Dictionary<int, dynamic>();    // 保有艦リスト
        static Dictionary<int, int> lst_slot = new Dictionary<int, int>();    // 装備保有リスト
        static Dictionary<string, string> map_deck = new Dictionary<string, string>();
        static string map_id;
 
        static void Main(string[] args)
        {
            ParseApiStart2();
            ParseApiPort();
 
            try
            {
                using (StreamReader sr = new StreamReader("Response.log"))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        string[] cols = line.Split('\t');
 
                        // URL
                        DispColor(ConsoleColor.DarkGreen , cols[0]);
                        string[] url = cols[0].Split('/');
 
                        // Request
                        NameValueCollection nvc = HttpUtility.ParseQueryString(cols[1]);
 
                        // Response
                        dynamic json = svdata2json(cols[2]);
                        dynamic data = json.api_data() ? json.api_data : null;
 
                        switch (url[4])
                        {
                            case "api_get_member":
                                switch (url[5])
                                {
                                    case "deck":
                                        Disp("艦隊情報");
                                        break;
                                    case "material":
                                        Disp("資源情報");
                                        break;
                                    case "mapinfo":
                                        GetMember_Mapinfo(data);
                                        break;
                                    case "mapcell":
                                        Disp("出撃開始");
                                        break;
                                    case "mission":
                                        Disp("遠征");
                                        break;
                                    case "ndock":
                                        Disp("入渠");
                                        break;
                                    case "practice":
                                        GetMember_Practice(data);
                                        break;
                                    case "questlist":
                                        GetMember_Questlist(data);
                                        break;
                                    case "record":
                                        break;
                                    case "ship2":
                                        api_deck = json.api_data_deck;
                                        CreateLstShip(data);
                                        DispDeck(1);
                                        break;
                                    case "ship3":
                                        Disp("艦隊・艦・装備データ");
                                        break;
                                    case "slot_item":
                                        GetMember_SlotItem(data);
                                        break;
                                    case "unsetslot":
                                        Disp("セットされていない装備");
                                        break;
                                    case "useitem":
                                        Disp("保有アイテム");
                                        break;
                                }
                                break;
                            case "api_port":
                                switch (url[5])
                                {
                                    case "port":
                                        Disp("母港");
                                        break;
                                }
                                break;
                            case "api_req_battle_midnight":
                                switch (url[5])
                                {
                                    case "battle":
                                        ReqBattleMidnight_Battle(data);
                                        break;
                                    case "sp_midnight":
                                        ReqBattleMidnight_SpMidnight(data);
                                        break;
                                }
                                break;
                            case "api_req_hensei":
                                switch (url[5])
                                {
                                    case "change":
                                        ReqHensei_Change(nvc);
                                        break;
                                }
                                break;
                            case "api_req_hokyu":
                                switch (url[5])
                                {
                                    case "charge":
                                        ReqHokyu_Charge(data);
                                        break;
                                }
                                break;
                            case "api_req_kaisou":
                                switch (url[5])
                                {
                                    case "powerup":
                                        ReqKaiou_Powerup(data);
                                        break;
                                    case "slotset":
                                        ReqKaisou_Slotset(nvc);
                                        break;
                                }
                                break;
                            case "api_req_kousyou":
                                switch (url[5])
                                {
                                    case "createitem":
                                        ReqKousyou_Createitem(nvc, data);
                                        break;
                                    case "getship":
                                        ReqKousyou_Getship(data);
                                        break;
                                }
                                break;
                            case "api_req_nyukyo":
                                switch (url[5])
                                {
                                    case "start":
                                        Disp("入渠開始 {0}", json.api_result_msg);
                                        break;
                                }
                                break;
                            case "api_req_map":
                                switch (url[5])
                                {
                                    case "next":
                                        ReqMap(data);
                                        break;
                                    case "start":
                                        ReqMap(data);
                                        break;
                                }
                                break;
                            case "api_req_member":
                                switch (url[5])
                                {
                                    case "get_practice_enemyinfo":
                                        ReqMember_GetPracticeEnemyinfo(data);
                                        break;
                                }
                                break;
                            case "api_req_mission":
                                switch (url[5])
                                {
                                    case "result":
                                        ReqMission_Result(nvc, data);
                                        break;
                                    case "start":
                                        ReqMission_Start(nvc, data);
                                        break;
                                }
                                break;
                            case "api_req_practice":
                                switch (url[5])
                                {
                                    case "battle":
                                        ReqPractice_Battle(data);
                                        break;
                                    case "battle_result":
                                        ReqPractice_BattleResult(data);
                                        break;
                                    case "midnight_battle":
                                        ReqPractice_MidnightBattle(data);
                                        break;
                                }
                                break;
                            case "api_req_quest":
                                switch (url[5])
                                {
                                    case "clearitemget":
                                        ReqQuest_Clearitemget(nvc, data);
                                        break;
                                    case "start":
                                        Disp("任務開始 {0}", json.api_result_msg);
                                        break;
                                    case "stop":
                                        Disp("任務停止 {0}", json.api_result_msg);
                                        break;
                                }
                                break;
                            case "api_req_sortie":
                                switch (url[5])
                                {
                                    case "battle":
                                        ReqSortie_Battle(data);
                                        break;
                                    case "battleresult":
                                        ReqSortie_Battleresult(data);
                                        break;
                                }
                                break;
                            case "api_start2":
                                break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Disp(e.ToString());
            }
 
            DispNDock();
            SaveMapDeck();
        }
 
        private static void DispColor(ConsoleColor color, string format, params object[] arg)
        {
            Console.ForegroundColor = color;
            Console.WriteLine(format, arg);
            Console.ResetColor();
        }
 
        private static void Disp(string format, params object[] arg)
        {
            DispColor(ConsoleColor.Gray, format, arg);
        }
 
        // 各種マスタ
        private static void ParseApiStart2()
        {
            dynamic json = ReadJson("api_start2.js");
 
            dynamic data = json.api_data;
            foreach (dynamic ship in data.api_mst_ship)
            {
                mst_ship[(int)ship.api_id] = ship;
            }
            foreach (dynamic slot in data.api_mst_slotitem)
            {
                mst_slot[(int)slot.api_id] = slot;
            }
        }
 
        // 母港情報
        private static void ParseApiPort()
        {
            dynamic json = ReadJson("api_port.js");
 
            dynamic data = json.api_data;
            api_deck = data.api_deck_port;
            CreateLstShip(data.api_ship);
        }
 
        // JSONファイル読み込み
        private static dynamic ReadJson(string path)
        {
            string svdata;
            using (StreamReader sr = new StreamReader("C:\\Projects\\kcsapi\\" + path))
            {
                svdata = sr.ReadToEnd();
            }
            return svdata2json(svdata);
        }
 
        private static dynamic svdata2json(string svdata)
        {
            string res = Regex.Replace(svdata, @"\\u(?<code>[0-9A-Fa-f]{4})",
                (Match m) => ((char)Convert.ToInt32(m.Groups["code"].Value, 16)).ToString());
            return DynamicJson.Parse(res.Substring(7));
        }
 
//==============================================================================
 
        private static void GetMember_Mapinfo(dynamic data)
        {
            Disp("出撃");
            foreach (dynamic map in data)
            {
                if (map.api_eventmap() && (int)map.api_cleared == 0)
                {
                    int max_maphp = (int)map.api_eventmap.api_max_maphp;
                    int now_maphp = (int)map.api_eventmap.api_now_maphp;
                    Disp("map:{0} {1}/{2} {3}%", (int)map.api_id,
                        now_maphp, max_maphp, 100 * now_maphp / max_maphp);
                }
            }
        }
 
        private static void GetMember_Practice(dynamic data)
        {
            Disp("演習");
            foreach (dynamic d in data)
            {
                Disp("{0}「{1}」", d.api_enemy_name, d.api_enemy_comment);
            }
        }
 
        private static void GetMember_Questlist(dynamic data)
        {
            Disp("任務 {0}/{1}", (int)data.api_disp_page, (int)data.api_page_count);
        }
 
        // 装備アイテム
        private static void GetMember_SlotItem(dynamic data)
        {
            lst_slot.Clear();
            foreach (dynamic d in data)
            {
                lst_slot[(int)d.api_id] = (int)d.api_slotitem_id;
            }
            Disp("装備アイテム保有数 {0}", lst_slot.Count);
        }
 
        // 夜戦
        private static void ReqBattleMidnight_Battle(dynamic data)
        {
            Disp("夜戦");
        }
 
        // 特殊夜戦
        private static void ReqBattleMidnight_SpMidnight(dynamic data)
        {
            MidnightBattle(data);
        }
 
        private static void ReqHensei_Change(NameValueCollection nvc)
        {
            Disp("編成/変更 id:{0} idx:{1} ship_id:{2}",
                nvc["api_id"], nvc["api_ship_idx"], nvc["api_ship_id"]);
        }
 
        private static void ReqHokyu_Charge(dynamic data)
        {
            Disp("補給");
            foreach (dynamic ship in data.api_ship)
            {
                dynamic lship = lst_ship[(int)ship.api_id];
                dynamic mship = mst_ship[(int)lship.api_ship_id];
                Disp("{0}", mship.api_name);
            }
            Disp("ボーキサイト消費:{0}", (int)data.api_use_bou);
        }
 
        private static void ReqKaiou_Powerup(dynamic data)
        {
            dynamic ship = data.api_ship;
            dynamic lship = lst_ship[(int)ship.api_id];
            dynamic mship = mst_ship[(int)lship.api_ship_id];
            Disp("合成開始 {0} 結果:{1}", mship.api_name, (int)data.api_powerup_flag);
        }
 
        private static void ReqKaisou_Slotset(NameValueCollection nvc)
        {
            Disp("id:{0} idx:{1} item_id:{2}", nvc["api_id"], nvc["api_slot_idx"], nvc["api_item_id"]);
        }
 
        private static void ReqKousyou_Createitem(NameValueCollection nvc, dynamic data)
        {
            Disp("開発開始");
 
            string str = "失敗";
            if (data.api_slot_item())
            {
                str = mst_slot[(int)data.api_slot_item.api_slotitem_id].api_name;
            }
 
            var mat = new string[4];
            for (var i = 0; i < mat.Length; i++)
            {
                mat[i] = nvc["api_item" + (i + 1)];
            }
            Disp("{0} {1}", string.Join("/", mat), str);
        }
 
        private static void ReqKousyou_Getship(dynamic data)
        {
            dynamic mship = mst_ship[(int)data.api_ship_id];
            Disp("建造 {0}", mship.api_name);
        }
 
        private static void ReqMap(dynamic data)
        {
            map_id = string.Format("{0}-{1}-{2}",
                (int)data.api_maparea_id, (int)data.api_mapinfo_no, (int)data.api_no);
            Disp("{0} 羅針盤:{1}", map_id, data.api_rashin_flg);
 
            if (data.api_itemget())
            {
                dynamic item = data.api_itemget;
                Disp("item:{0} {1}", (int)item.api_id, (int)item.api_getcount);
            }
        }
 
        private static void ReqMember_GetPracticeEnemyinfo(dynamic data)
        {
            Disp("艦隊名:{0}", data.api_deckname);
            foreach (dynamic ship in data.api_deck.api_ships)
            {
                if (!ship.api_ship_id()) break;
                Disp("lv{0} {1}",
                    (int)ship.api_level, GetShipName((int)ship.api_ship_id));
            }
        }
 
        private static void ReqMission_Result(NameValueCollection nvc, dynamic data)
        {
            Disp("遠征:{0} 艦隊:{1} 結果:{2}",
                data.api_quest_name, nvc["api_deck_id"], (int)data.api_clear_result);
            int[] m = data.api_get_material;
            Disp("燃:{0} 弾:{1} 鋼:{2} ボ:{3}", m[0], m[1], m[2], m[3]);
        }
 
        private static void ReqMission_Start(NameValueCollection nvc, dynamic data)
        {
            Disp("遠征開始 {0}", data.api_complatetime_str);
            Disp("艦隊:{0} id:{1}", nvc["api_deck_id"], nvc["api_mission_id"]);
        }
 
        private static void ReqPractice_Battle(dynamic data)
        {
            Battle(data);
        }
 
        private static void ReqPractice_BattleResult(dynamic data)
        {
            BattleResult(data);
        }
 
        private static void ReqPractice_MidnightBattle(dynamic data)
        {
            MidnightBattle(data);
        }
 
        private static void ReqQuest_Clearitemget(NameValueCollection nvc, dynamic data)
        {
            Disp("任務/達成 {0} ボーナス:{1}", nvc["api_quest_id"], (int)data.api_bounus_count);
            int[] m = data.api_material;
            Disp("燃:{0} 弾:{1} 鋼:{2} ボ:{3}", m[0], m[1], m[2], m[3]);
        }
 
        private static void ReqSortie_Battle(dynamic data)
        {
            Battle(data);
        }
 
        private static void ReqSortie_Battleresult(dynamic data)
        {
            BattleResult(data);
 
            // 艦取得
            Disp("艦保有数 {0} 隻", lst_ship.Count);
            string ship_type = "";
            string ship_name = "";
            if (data.api_get_ship())
            {
                dynamic ship = data.api_get_ship;
                ship_type = ship.api_ship_type;
                ship_name = ship.api_ship_name;
            }
 
            string line = string.Join(",",
                DateTime.Now.ToString(), map_id, data.api_win_rank, ship_type, ship_name);
            Disp(line);
            using (StreamWriter sw = new StreamWriter("get_ship.csv", true, Encoding.Default))
            {
                sw.WriteLine(line);
            }
 
            // 艦隊名保存
            map_deck[map_id] = data.api_enemy_info.api_deck_name;
        }
 
        private static void Battle(dynamic data)
        {
            int[] ship_ke = data.api_ship_ke;
            for (int i = 1; i < ship_ke.Length; i++)
            {
                int id = ship_ke[i];
                if (id < 0) continue;
 
                dynamic mship = mst_ship[id];
                Disp("{0} lv{1} hp{2} {3} {4}", i, (int)data.api_ship_lv[i], (int)data.api_maxhps[6 + i],
                    mship.api_name, mship.api_yomi);
            }
 
            dynamic form = data.api_formation;
            Disp("自:{0} 敵:{1} {2}",
                formation[(int)form[0]], formation[(int)form[1]], intercept[(int)form[2]]);
            Disp("艦隊:{0} 夜戦:{1}", (int)data.api_dock_id, (int)data.api_midnight_flag);
            /*
            api_kouku	航空
             api_stage1	
              api_disp_seiku
              api_f_count	味方制空値
              api_f_lostcount
             api_stage3
              api_edam	敵ダメージ
 
            api_opening_atack	開幕雷撃
             api_edam	敵ダメージ
             api_frai	味方攻撃対象
             */
        }
 
        private static void MidnightBattle(dynamic data)
        {
            dynamic hougeki = data.api_hougeki;
            for (int i = 1; i < ((int[])hougeki.api_at_list).Length; i++)
            {
                Disp("at{0} sp{1}",
                    (int)hougeki.api_at_list[i], (int)hougeki.api_sp_list[i]);
            }
            // at_list 攻撃番号配列
            // cl_list クリティカル
            // damage  ダメージ
            // df_list 防御番号
            // si_list 攻撃装備id slot item
            // sp_list 特殊攻撃 1:連撃 3:カットイン雷撃
        }
 
        private static void BattleResult(dynamic data)
        {
            Disp("敵艦隊名:{0}", data.api_enemy_info.api_deck_name);
            Disp("win_rank:{0} mvp:{1}", data.api_win_rank, (int)data.api_mvp);
            Disp("基本経験値:{0} 提督経験値:{1}", (int)data.api_get_base_exp, (int)data.api_get_exp);
            // api_dests  撃沈数
            // api_destsf 旗艦撃沈
        }
 
//==============================================================================
 
        // 保有艦リスト
        private static void CreateLstShip(dynamic ship)
        {
            Disp("保有艦リスト更新 {0}", DateTime.Now);
            lst_ship.Clear();
            foreach (dynamic s in ship)
            {
                lst_ship[(int)s.api_id] = s;
            }
            Disp("艦保有数 {0} 隻", lst_ship.Count);
        }
 
        // 艦名の取得
        private static string GetShipName(int ship_id)
        {
            dynamic mship = mst_ship[ship_id];
            return mship.api_name;
        }
 
        // 艦隊の表示
        private static void DispDeck(int id)
        {
            foreach (dynamic i in api_deck[id - 1].api_ship)
            {
                int ship_uid = (int)i;
                if (ship_uid < 0) break;
 
                dynamic ship = lst_ship[ship_uid];
                dynamic mship = mst_ship[(int)ship.api_ship_id];
                Disp("lv{0}.{1:D2} co{2} 燃{4}/弾{5} hp{3}% {6}",
                    (int)ship.api_lv, (int)ship.api_exp[2], (int)ship.api_cond,
                    100 * (int)ship.api_nowhp / (int)ship.api_maxhp,
                    Math.Round(10 * ship.api_fuel / mship.api_fuel_max),
                    Math.Round(10 * ship.api_bull / mship.api_bull_max),
                    mship.api_name);
            }
        }
 
        // 入渠ドックの表示
        private static void DispNDock()
        {
            var list = new List<Tuple<int, string>>();
            foreach (var kvp in lst_ship)
            {
                dynamic ship = kvp.Value;
                int hp = (int)ship.api_maxhp - (int)ship.api_nowhp;
                if (0 < hp) {
                    int sec = (int)ship.api_ndock_time / 1000;
                    int nowhp = (int)ship.api_nowhp;
                    int maxhp = (int)ship.api_maxhp;
                    TimeSpan ts = new TimeSpan(0, 0, sec);
                    list.Add(Tuple.Create(sec, string.Format("{0} {1} {2}/{3} {4}", ts.ToString("g"),
                        maxhp - nowhp, nowhp, maxhp, GetShipName((int)ship.api_ship_id))));
                }
            }
            list.Sort((Tuple<int, string>t1, Tuple<int, string>t2) => t2.Item1 - t1.Item1);
            foreach (var t in list)
            {
                Disp(t.Item2);
            }
        }
 
        private static void LoadMapDeck()
        {
            using (var sr = new StreamReader("map_deck.csv"))
            {
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    var cols = line.Split(',');
                    map_deck[cols[0]] = cols[1];
                }
            }
        }
 
        private static void SaveMapDeck()
        {
            using (var sw = new StreamWriter("map_deck.csv"))
            {
                foreach (var kvp in map_deck)
                {
                    sw.WriteLine("{0},{1}", kvp.Key, kvp.Value);
                }
            }
        }
    }
}
 
最終更新:2014年05月23日 04:25