private void Nekoxy_SessionComplete(Session s) { if (!s.Response.ContentType.Equals("text/html")) return; if (!s.Response.BodyAsString.StartsWith(@"{")) return; var api = s.Request.PathAndQuery.Split('?').First(); var request = s.Request.BodyAsString; var response = s.Response.BodyAsString; SessionComplete?.Invoke(api, request, response); }
private static void ITowerProxy_AfterSessionComplete(Session s) { if (s.Response.MimeType.Equals("text/html")) { AfterSessionComplete_Text?.Invoke(s); } else { //Console.WriteLine(string.Format("ContentType = {0}", s.Response.ContentType)); } }
private void HttpGetMapResource(Session s) { var filePath = s.Request.PathAndQuery.Split('?').First(); s.SaveResponseBody(PluginSettings.Paths.CacheDirPath + filePath); Debug.WriteLine($"{this.currentMapAreaId}-{this.currentMapInfoNo}:{filePath}"); this.resourceUrlMapping .GetOrAdd(this.currentMapAreaId, new ConcurrentDictionary<int, string>()) .AddOrUpdate(this.currentMapInfoNo, filePath, (_, __) => filePath); this.resourceUrlMapping.Serialize(PluginSettings.Paths.ResourceUrlMappingFileName); }
/// <summary> /// read the after-session, determinate whether it will send to kancolle-db.net /// </summary> public void ExecuteSession( Session session ) { if ( string.IsNullOrEmpty( OAuth ) ) { return; } // find the url in dict. string url = session.Request.PathAndQuery; if ( apis.Contains( url ) ) { PostToServer( session ); } }
private void AfterSessionComplete_Debug(Session s) { var query = new RequestQuery(s.Request.PathAndQuery); var apiname = query.GetCtl("ctl"); if (string.Empty.Equals(apiname)) return; var xmldoc = new XmlDocument(); xmldoc.LoadXml(Encoding.UTF8.GetString(Utilities.Unzip(s.Response.Body))); #if DEBUG Utilities.HistoryWriter(apiname, xmldoc); #endif Utilities.XmlWriter(apiname, xmldoc); if (!ApisExtension.List().Contains(apiname)) { Console.WriteLine("******************************************************"); Console.WriteLine(string.Format("未登録のAPIが来ました。: apiname = {0}", apiname)); Console.WriteLine(s.Request.PathAndQuery); Console.WriteLine("******************************************************"); } }
private void AfterSessionComplete_Text(Session s) { try { var query = new RequestQuery(s.Request.PathAndQuery); var apiname = query.GetCtl("ctl"); if (string.Empty.Equals(apiname)) return; var apis = ApisExtension.List(); if (!apis.Contains(apiname)) return; // 未登録のAPIの場合は抜けちゃうよ。 //小細工用「searchnext」 if (this.searchnext != null) { Searchnext_Complete?.Invoke(this.searchnext); this.searchnext = null; } Console.WriteLine(string.Format("apiname = {0}", apiname)); switch (ApisExtension.Value(apiname)) { case APIS.batheinit: Batheinit_Complete?.Invoke(Utilities.Deserialize<Batheinit>(s.Response.Body)); break; case APIS.cardchange: Cardchange_Complete?.Invoke(Utilities.Deserialize<Cardchange>(s.Response.Body)); break; case APIS.searchnext: this.searchnext = Utilities.Deserialize<Searchnext>(s.Response.Body); break; case APIS.groupexit: Groupexit_Complete?.Invoke(Utilities.Deserialize<Groupexit>(s.Response.Body)); break; case APIS.cardmultidel: Cardmultidel_Complete?.Invoke(Utilities.Deserialize<Cardmultidel>(s.Response.Body)); break; case APIS.restset: Restset_Complete?.Invoke(Utilities.Deserialize<Restset>(s.Response.Body)); break; case APIS.restinit: Restinit_Complete?.Invoke(Utilities.Deserialize<Restinit>(s.Response.Body)); break; default: break; } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }
void HttpProxy_AfterSessionComplete( Session session ) { Utility.Configuration.ConfigurationData.ConfigConnection c = Utility.Configuration.Config.Connection; string baseurl = session.Request.PathAndQuery; //debug //Utility.Logger.Add( 1, baseurl ); // request if ( baseurl.Contains( "/kcsapi/" ) ) { string url = baseurl; string body = session.Request.BodyAsString; //保存 if ( c.SaveReceivedData && c.SaveRequest ) { Task.Run( (Action)( () => { SaveRequest( url, body ); } ) ); } UIControl.BeginInvoke( (Action)( () => { LoadRequest( url, body ); } ) ); } //response //保存 if ( c.SaveReceivedData ) { try { if ( !Directory.Exists( c.SaveDataPath ) ) Directory.CreateDirectory( c.SaveDataPath ); if ( c.SaveResponse && baseurl.Contains( "/kcsapi/" ) ) { // 非同期で書き出し処理するので取っておく // stringはイミュータブルなのでOK string url = baseurl; string body = session.Response.BodyAsString; Task.Run( (Action)( () => { SaveResponse( url, body ); } ) ); } else if ( baseurl.Contains( "/kcs/" ) && ( ( c.SaveSWF && session.Response.MimeType == "application/x-shockwave-flash" ) || c.SaveOtherFile ) ) { string saveDataPath = c.SaveDataPath; // スレッド間の競合を避けるため取っておく string tpath = string.Format( "{0}\\{1}", saveDataPath, baseurl.Substring( baseurl.IndexOf( "/kcs/" ) + 5 ).Replace( "/", "\\" ) ); { int index = tpath.IndexOf( "?" ); if ( index != -1 ) { if ( Utility.Configuration.Config.Connection.ApplyVersion ) { string over = tpath.Substring( index + 1 ); int vindex = over.LastIndexOf( "VERSION=", StringComparison.CurrentCultureIgnoreCase ); if ( vindex != -1 ) { string version = over.Substring( vindex + 8 ).Replace( '.', '_' ); tpath = tpath.Insert( tpath.LastIndexOf( '.', index ), "_v" + version ); index += version.Length + 2; } } tpath = tpath.Remove( index ); } } // 非同期で書き出し処理するので取っておく byte[] responseCopy = new byte[session.Response.Body.Length]; Array.Copy( session.Response.Body, responseCopy, session.Response.Body.Length ); Task.Run( (Action)( () => { try { lock ( this ) { // 同時に書き込みが走るとアレなのでロックしておく Directory.CreateDirectory( Path.GetDirectoryName( tpath ) ); //System.Diagnostics.Debug.WriteLine( oSession.fullUrl + " => " + tpath ); using ( var sw = new System.IO.BinaryWriter( System.IO.File.OpenWrite( tpath ) ) ) { sw.Write( responseCopy ); } } Utility.Logger.Add( 1, string.Format( "通信からファイル {0} を保存しました。", tpath.Remove( 0, saveDataPath.Length + 1 ) ) ); } catch ( IOException ex ) { //ファイルがロックされている; 頻繁に出るのでエラーレポートを残さない Utility.Logger.Add( 3, "通信内容の保存に失敗しました。 " + ex.Message ); } } ) ); } } catch ( Exception ex ) { Utility.ErrorReporter.SendErrorReport( ex, "通信内容の保存に失敗しました。" ); } } if ( baseurl.Contains( "/kcsapi/" ) && session.Response.MimeType == "text/plain" ) { // 非同期でGUIスレッドに渡すので取っておく // stringはイミュータブルなのでOK string url = baseurl; string body = session.Response.BodyAsString; UIControl.BeginInvoke( (Action)( () => { LoadResponse( url, body ); } ) ); // kancolle-db.netに送信する if ( Utility.Configuration.Config.Connection.SendDataToKancolleDB ) { Task.Run( (Action)( () => DBSender.ExecuteSession( session ) ) ); } } if ( ServerAddress == null && baseurl.Contains( "/kcsapi/" ) ) { ServerAddress = session.Request.Headers.Host; } }
private static void InvokeAfterSessionComplete(Session session) => AfterSessionComplete?.Invoke(session);
private static kcsapi_questlist Serialize(Session session) { try { var djson = DynamicJson.Parse(session.GetResponseAsJson()); var questlist = new kcsapi_questlist { api_count = Convert.ToInt32(djson.api_data.api_count), api_disp_page = Convert.ToInt32(djson.api_data.api_disp_page), api_page_count = Convert.ToInt32(djson.api_data.api_page_count), api_exec_count = Convert.ToInt32(djson.api_data.api_exec_count), }; if (djson.api_data.api_list != null) { var list = new List<kcsapi_quest>(); var serializer = new DataContractJsonSerializer(typeof(kcsapi_quest)); foreach (var x in (object[])djson.api_data.api_list) { try { list.Add(serializer.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(x.ToString()))) as kcsapi_quest); } catch (SerializationException ex) { // 最後のページで任務数が 5 に満たないとき、api_list が -1 で埋められるというクソ API のせい Debug.WriteLine(ex.Message); } } questlist.api_list = list.ToArray(); } return questlist; } catch (Exception ex) { Debug.WriteLine(ex); return null; } }
private void PostToServer( Session session ) { string oauth = OAuth; string url = session.Request.PathAndQuery; string request = session.Request.BodyAsString; string response = session.Response.BodyAsString; request = RequestRegex.Replace( request, "" ); try { //* using ( System.Net.WebClient wc = new System.Net.WebClient() ) { wc.Headers["User-Agent"] = "ElectronicObserver/v" + SoftwareInformation.VersionEnglish; if ( Proxy != null ) { wc.Proxy = Proxy; } System.Collections.Specialized.NameValueCollection post = new System.Collections.Specialized.NameValueCollection(); post.Add( "token", oauth ); // agent key for 'ElectronicObserver' // https://github.com/about518/kanColleDbPost/issues/3#issuecomment-105534030 post.Add( "agent", "L57Mi4hJeCYinbbBSH5K" ); post.Add( "url", url ); post.Add( "requestbody", request ); post.Add( "responsebody", response ); wc.UploadValuesCompleted += ( sender, e ) => { if ( e.Error != null ) { // 結構頻繁に出るのでレポートは残さない方針で 申し訳ないです //Utility.ErrorReporter.SendErrorReport( e.Error, string.Format( "艦これ統計データベースへの {0} の送信に失敗しました。", url.Substring( url.IndexOf( "/api" ) + 1 ) ) ); Utility.Logger.Add( 1, string.Format( "艦これ統計データベースへの {0} の送信に失敗しました。{1}", url.Substring( url.IndexOf( "/api" ) + 1 ), e.Error.Message ) ); } else { Utility.Logger.Add( 0, string.Format( "艦これ統計データベースへ {0} を送信しました。", url.Substring( url.IndexOf( "/api" ) + 1 ) ) ); } }; wc.UploadValuesAsync( new Uri( "http://api.kancolle-db.net/2/" ), post ); } //*/ } catch ( Exception ex ) { Utility.ErrorReporter.SendErrorReport( ex, "艦これ統計データベースへの送信中にエラーが発生しました。" ); } }
public static string GenDetail(Api api, Session s) { bool showDefaultDescription = false; switch (api) { case Api.api_req_kousyou_createship: { var req = SvData.Parse<kcsapi_createship>(s).Request; return string.Format("第{0}建造ドック ({1}/{2}/{3}/{4}/{5}) で建造開始", req["api_kdock_id"], req["api_item1"], req["api_item2"], req["api_item3"], req["api_item4"], req["api_item5"]); } case Api.api_req_kousyou_getship: { var svdata = SvData.Parse<kcsapi_kdock_getship>(s); var req = svdata.Request; var res = svdata.Data; return string.Format("第{0}建造ドックで {1} を入手", req["api_kdock_id"], KanColleClient.Current.Master.Ships[res.api_ship_id].Name); } case Api.api_req_kousyou_createitem: { var svdata = SvData.Parse<kcsapi_createitem>(s); var req = svdata.Request; var slotitem = new CreatedSlotItem(svdata.Data); return string.Format("({0}/{1}/{2}/{3}){4} 開発{5}", req["api_item1"], req["api_item2"], req["api_item3"], req["api_item4"], slotitem.Succeed ? " " + slotitem.SlotItemInfo.Name : "", slotitem.Succeed ? "成功" : "失敗"); } case Api.api_req_sortie_battleresult: { var data = SvData.Parse<kcsapi_battleresult>(s).Data; return string.Format("{0} {1}:ランク{2} {3}", data.api_quest_name, data.api_enemy_info.api_deck_name, data.api_win_rank, data.api_get_flag[1] == 1 ? "ドロップ:" + data.api_get_ship.api_ship_name : ""); } case Api.api_req_combined_battle_battleresult: { var data = SvData.Parse<kcsapi_combined_battle_battleresult>(s).Data; return string.Format("{0} {1}:ランク{2} {3}", data.api_quest_name, data.api_enemy_info.api_deck_name, data.api_win_rank, data.api_get_flag[1] == 1 ? "ドロップ:" + data.api_get_ship.api_ship_name : ""); } default: return showDefaultDescription ? api.GetDetail() ?? "" : ""; } }
public Record(DateTime timestamp, Api api, Session s) { this.Timestamp = timestamp; this.Api = api; this.Detail = GenDetail(api, s); }