/*
* プロジェクト参照
* ・アセンブリ/フレームワーク
* ・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);
}
}
}
}
}