Пример #1
0
        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);
        }
Пример #2
0
 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 );
            }
        }
Пример #5
0
        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("******************************************************");
            }
        }
Пример #6
0
        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());
            }
        }
Пример #7
0
		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;
			}

		}
Пример #8
0
 private static void InvokeAfterSessionComplete(Session session)
     => AfterSessionComplete?.Invoke(session);
Пример #9
0
		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;
			}
		}
Пример #10
0
        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, "艦これ統計データベースへの送信中にエラーが発生しました。" );
            }
        }
Пример #11
0
        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() ?? "" : "";
            }
        }
Пример #12
0
 public Record(DateTime timestamp, Api api, Session s)
 {
     this.Timestamp = timestamp;
     this.Api = api;
     this.Detail = GenDetail(api, s);
 }