diff --git a/.classpath b/.classpath index bb375ec..9f152e5 100644 --- a/.classpath +++ b/.classpath @@ -1,13 +1,17 @@ - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore index eedcf4f..6978eb6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /fuuko.xml /fuuko08.xml /xml +/bin diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index ead6ab2..bc3368e 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,3 @@ eclipse.preferences.version=1 -encoding//walker/Go.java=UTF-8 +encoding//src/walker/Go.java=UTF-8 +encoding/=UTF-8 diff --git a/README.md b/README.md index d7cf870..ab2a6c4 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,38 @@ MAWalker ======== +特别说明 +-------- +本人已弃坑,该版本不再维护,另贡献一个改进的版本,见隔壁[MAWalkerMod](https://github.com/tsubasa617/MAWalkerMod),强烈推荐
+ ![MAWalker](http://wjsjwr.org/ma-walker/ma.jpg "MAWalker") ### 解放双手 解放手机 尽早弃坑 保住智商 + +原作者 +-------- [wjsjwr.org/ma-walker](http://wjsjwr.org/ma-walker)
如果你只是使用者 -------- -请进入[wjsjwr.org/ma-walker](http://wjsjwr.org/ma-walker)下载二进制文件,并按说明使用 +1、安装java7,下载地址为www.java.com
+2、从这里下载并安装长度补丁,补丁包名为UnlimitedJCEPolicyJDK7.zip
+3、从这里下载go.jar和c.xml
+4、用记事本打开c.xml文件并按提示编辑
+5、新建一个记事本文件,输入java -jar go.jar c.xml,保存为bat文件,与其他两个文件放在同一文件夹下面
+6、运行bat文件
+ + +安装补丁的方法 +-------- +将补丁解压得到的两个jar文件解压缩到你的java7安装文件夹下的lib/security中
+java7默认安装在C盘的C:\Program Files\java\jre7\或者C:\Program Files(x86)\java\jre7\下
+ + +可能出现的问题 +-------- +如果出现运行java -jar go.jar c.xml时出现不能识别java命令的情况,请百度“java 修改path变量”
如果你想写代码 @@ -17,4 +40,4 @@ MAWalker 建议先看一下[面向开发者的MAWalker使用说明](http://wjsjwr.org/blog/2013/08/413) -### 祝大家玩得愉快 弃得爽快 \ No newline at end of file +### 祝大家玩得愉快 弃得爽快 diff --git a/UnlimitedJCEPolicyJDK7.zip b/UnlimitedJCEPolicyJDK7.zip new file mode 100644 index 0000000..0a6890c Binary files /dev/null and b/UnlimitedJCEPolicyJDK7.zip differ diff --git a/action/GetFairyList.java b/action/GetFairyList.java deleted file mode 100644 index 95c5f65..0000000 --- a/action/GetFairyList.java +++ /dev/null @@ -1,192 +0,0 @@ -package action; - -import info.FairyBattleInfo; -import info.FairySelectUser; - -import java.util.ArrayList; - -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathFactory; - -import org.apache.http.NameValuePair; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import walker.ErrorData; -import walker.Go; -import walker.Info; -import walker.Process; -import action.ActionRegistry.Action; - -public class GetFairyList { - public static final Action Name = Action.GET_FAIRY_LIST; - - private static final String URL_FAIRY_LIST = "http://web.million-arthurs.com/connect/app/private_fairy/private_fairy_select?cyt=1"; - - private static byte[] response; - - public static boolean run() throws Exception { - try { - response = Process.network.ConnectToServer(URL_FAIRY_LIST, new ArrayList(), false); - } catch (Exception ex) { - ErrorData.currentDataType = ErrorData.DataType.text; - ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; - ErrorData.text = ex.getMessage(); - throw ex; - } - - Document doc; - try { - doc = Process.ParseXMLBytes(response); - } catch (Exception ex) { - ErrorData.currentDataType = ErrorData.DataType.bytes; - ErrorData.currentErrorType = ErrorData.ErrorType.FairyListDataError; - ErrorData.bytes = response; - throw ex; - } - - try { - return parse(doc); - } catch (Exception ex) { - throw ex; - } - - } - private static boolean parse(Document doc) throws Exception { - - XPathFactory factory = XPathFactory.newInstance(); - XPath xpath = factory.newXPath(); - - - try { - if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { - ErrorData.currentErrorType = ErrorData.ErrorType.FairyListResponse; - ErrorData.currentDataType = ErrorData.DataType.text; - ErrorData.text = xpath.evaluate("/response/header/error/message", doc); - return false; - } - - if (!xpath.evaluate("//remaining_rewards", doc).equals("0")) { - if (Info.receiveBattlePresent) { - Process.info.events.push(Info.EventType.fairyReward); - } - } - - //获取放妖的用户 - NodeList fairyuser = (NodeList)xpath.evaluate("//fairy_select/user", doc, XPathConstants.NODESET); - for(int i = 0; i < fairyuser.getLength(); i++) - { - Node f = fairyuser.item(i).getFirstChild(); - FairySelectUser fsu = new FairySelectUser(); - do { - if (f.getNodeName().equals("id")) { - fsu.userID = f.getFirstChild().getNodeValue(); - } else if (f.getNodeName().equals("name")) { - fsu.userName = f.getFirstChild().getNodeValue(); - } - f = f.getNextSibling(); - } while (f != null); - if(!Process.info.FairySelectUserList.containsKey(fsu.userID)) - { - Process.info.FairySelectUserList.put(fsu.userID,fsu); - } - } - - - // TODO: 这两周先是只寻找0BC的,之后再扩展 - //NodeList fairy = (NodeList)xpath.evaluate("//fairy_select/fairy_event[put_down=4]/fairy", doc, XPathConstants.NODESET); - NodeList fairy = (NodeList)xpath.evaluate("//fairy_select/fairy_event[put_down=1]/fairy", doc, XPathConstants.NODESET); - - ArrayList fbis = new ArrayList(); - for (int i = 0; i < fairy.getLength(); i++) { - Node f = fairy.item(i).getFirstChild(); - FairyBattleInfo fbi = new FairyBattleInfo(); - boolean attack_flag = false; - do { - if (f.getNodeName().equals("serial_id")) { - fbi.SerialId = f.getFirstChild().getNodeValue(); - } else if (f.getNodeName().equals("discoverer_id")) { - fbi.UserId = f.getFirstChild().getNodeValue(); - } else if (f.getNodeName().equals("lv")) { - fbi.FairyLevel = f.getFirstChild().getNodeValue(); - } else if (f.getNodeName().equals("name")) { - fbi.FairyName = f.getFirstChild().getNodeValue(); - } else if (f.getNodeName().equals("rare_flg")) { - if (f.getFirstChild().getNodeValue().equals("1")) { - fbi.Type = FairyBattleInfo.PRIVATE | FairyBattleInfo.RARE; - } else { - fbi.Type = FairyBattleInfo.PRIVATE; - } - } else if (f.getNodeName().equals("hp")){ - fbi.fairyCurrHp = Integer.parseInt(f.getFirstChild().getNodeValue()); - } else if (f.getNodeName().equals("hp_max")){ - fbi.fairyMaxHp = Integer.parseInt(f.getFirstChild().getNodeValue()); - } - f = f.getNextSibling(); - } while (f != null); - if (Info.AllowAttackSameFairy) { - fbis.add(fbi); - } else { - for (FairyBattleInfo bi : Process.info.LatestFairyList) { - if (bi.equals(fbi)) { - // 已经舔过 - attack_flag = true; - break; - } - } - if (!attack_flag) fbis.add(fbi); - } - - } - - - if (fbis.size() > 1) Process.info.events.push(Info.EventType.fairyAppear); // 以便再次寻找 - if (fbis.size() > 0) { - Process.info.events.push(Info.EventType.gotoFloor); - Process.info.events.push(Info.EventType.recvPFBGood); - Process.info.events.push(Info.EventType.fairyCanBattle); - Process.info.fairy = new FairyBattleInfo(fbis.get(0)); - } - - NodeList fairy1 = (NodeList) xpath.evaluate( - "//fairy_select/fairy_event[put_down=5]/fairy", doc, - XPathConstants.NODESET); - - int aa = fairy1.getLength(); - - Go.log("找到" + aa + "个可赞的PFB..."); - for (int i = 0; i < fairy1.getLength(); i++) { - Node f = fairy1.item(i).getFirstChild(); - String serial_Id = ""; - String user_Id = ""; - do { - if (f.getNodeName().equals("serial_id")) { - serial_Id = f.getFirstChild().getNodeValue(); - } else if (f.getNodeName().equals("discoverer_id")) { - user_Id = f.getFirstChild().getNodeValue(); - } - f = f.getNextSibling(); - } while (f != null); - Process.info.PFBGoodList.push(new info.PFBGood(serial_Id, user_Id)); - } - if(!Process.info.PFBGoodList.isEmpty()) - { - Process.info.events.push(Info.EventType.PFBGood); - } - - Process.info.SetTimeoutByAction(Name); - - } catch (Exception ex) { - if (ErrorData.currentErrorType != ErrorData.ErrorType.none) throw ex; - ErrorData.currentDataType = ErrorData.DataType.bytes; - ErrorData.currentErrorType = ErrorData.ErrorType.FairyListDataParseError; - ErrorData.bytes = response; - throw ex; - } - - return true; - - } -} diff --git a/c.xml b/c.xml index 5bbbec3..105efdc 100644 --- a/c.xml +++ b/c.xml @@ -2,21 +2,56 @@ - Million/236 (t03gchn; t03gzc; 4.1.2) samsung/t03gzc/t03gchn:4.1.2/JZO54K/N7100ZCDMD3:user/release-keys GooglePlay - 1 - + - 1 - 1 + 0 + 0 1 @@ -30,18 +65,10 @@ + - + FairyDeck 0 @@ -68,12 +95,11 @@ 0 + + + - - sell + 1 diff --git a/go.jar b/go.jar new file mode 100644 index 0000000..fe616c8 Binary files /dev/null and b/go.jar differ diff --git a/httpcomponents-client-4.2.3/LICENSE.txt b/httpcomponents-client-4.2.3/LICENSE.txt deleted file mode 100644 index d9a10c0..0000000 --- a/httpcomponents-client-4.2.3/LICENSE.txt +++ /dev/null @@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/httpcomponents-client-4.2.3/NOTICE.txt b/httpcomponents-client-4.2.3/NOTICE.txt deleted file mode 100644 index ea1911c..0000000 --- a/httpcomponents-client-4.2.3/NOTICE.txt +++ /dev/null @@ -1,6 +0,0 @@ -Apache HttpComponents Client -Copyright 1999-2012 The Apache Software Foundation - -This product includes software developed by -The Apache Software Foundation (http://www.apache.org/). - diff --git a/httpcomponents-client-4.2.3/README.txt b/httpcomponents-client-4.2.3/README.txt deleted file mode 100644 index b4b201c..0000000 --- a/httpcomponents-client-4.2.3/README.txt +++ /dev/null @@ -1,77 +0,0 @@ -Apache HttpComponents Client -============================ - -Welcome to the HttpClient component of the Apache HttpComponents project. - -Building Instructions ---------------------- - -For building from source instructions please refer to BUILDING.txt. - -Dependencies ------------- - -HttpClient main module requires Java 5.0 compatible runtime and -depends on the following external libraries: - -* Apache HttpComponents HttpCore -* Apache Commons Logging -* Apache Commons Codec - -(for detailed information on external dependencies please see pom.xml) - -HttpMime module is optional and requires Java 5.0 compatible runtime -and depends on the following external libraries: - -* Apache HttpComponents HttpCore -* Apache Commons Logging - -(for detailed information on external dependencies please see pom.xml) - -Licensing ---------- - -Apache HttpComponents Client is licensed under the Apache License 2.0. -See the files called LICENSE.txt and NOTICE.txt for more information. - -Cryptographic Software Notice ------------------------------ - -This distribution may include software that has been designed for use -with cryptographic software. The country in which you currently reside -may have restrictions on the import, possession, use, and/or re-export -to another country, of encryption software. BEFORE using any encryption -software, please check your country's laws, regulations and policies -concerning the import, possession, or use, and re-export of encryption -software, to see if this is permitted. See -for more information. - -The U.S. Government Department of Commerce, Bureau of Industry and -Security (BIS), has classified this software as Export Commodity -Control Number (ECCN) 5D002.C.1, which includes information security -software using or performing cryptographic functions with asymmetric -algorithms. The form and manner of this Apache Software Foundation -distribution makes it eligible for export under the License Exception -ENC Technology Software Unrestricted (TSU) exception (see the BIS -Export Administration Regulations, Section 740.13) for both object -code and source code. - -The following provides more details on the included software that -may be subject to export controls on cryptographic software: - - Apache HttpComponents Client interfaces with the - Java Secure Socket Extension (JSSE) API to provide - - - HTTPS support - - Apache HttpComponents Client does not include any - implementation of JSSE. - -Contact -------- - - o For general information visit the main project site at - http://hc.apache.org/ - - o For current status information visit the status page at - http://hc.apache.org/status.html diff --git a/httpcomponents-client-4.2.3/RELEASE_NOTES.txt b/httpcomponents-client-4.2.3/RELEASE_NOTES.txt deleted file mode 100644 index 6286341..0000000 --- a/httpcomponents-client-4.2.3/RELEASE_NOTES.txt +++ /dev/null @@ -1,1418 +0,0 @@ -Release 4.2.3 -------------------- - -HttpClient 4.2.3 (GA) is a bug fix release that addresses a number of issues reported since -release 4.2.2. This release also includes a thoroughly reworked NTLM authentication engine -which should result in a better compatibility with the newest Microsoft products. - -Users of HttpClient 4.x are advised to upgrade. - -Changelog -------------------- - -* [HTTPCLIENT-1296] NPE gets thrown if you combine a default host with a virtual host - that has a -1 value for the port. - Contributed by Karl Wright - -* [HTTPCLIENT-1290] 304 cached response never reused with If-modified-since conditional - requests. - Contributed by Francois-Xavier Bonnet - -* [HTTPCLIENT-1291] Absolute request URIs without an explicitly specified path are rewritten - to have "/" path). - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1286] Request URI rewriting is inconsistent - URI fragments are not removed - from absolute request URIs. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1284] HttpClient incorrectly generates Host header when physical connection - route differs from the host name specified in the request URI. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1293] Kerberos and SPNego auth schemes use incorrect authorization header name - when authenticating with a proxy. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1283] NTLM needs to use Locale-independent form of - toUpperCase(). - Contributed by Karl Wright - -* [HTTPCLIENT-1279] Target host responding with status 407 (proxy authentication required) - causes an NPE. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1281] GzipDecompressingEntity does not release InputStream when an IOException - occurs while reading the Gzip header - Contributed by Francois-Xavier Bonnet - -* [HTTPCLIENT-1277] Caching client sends a 304 to an unconditional request. - Contributed by Francois-Xavier Bonnet - -* [HTTPCLIENT-1278] Update NTLM documentation. - Contributed by Karl Wright - -* SystemDefaultHttpClient misinterprets 'http.keepAlive' default value and disables - connection persistence if the system property is not set. This causes connection - based authentication schemes such as NTLM to fail. - -* [HTTPCLIENT-1276] cache update on a 304 response causes NPE. - Contributed by Francois-Xavier Bonnet - -* [HTTPCLIENT-1273] DecompressingHttpClient does not automatically consume response - content in case of an i/o, HTTP or runtime exception thrown by the decompressing - protocol interceptor leading to a potential connection leak. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1268] NTLM engine refactor fix, to correct a buffer overrun, and get NTLMv2 - flags right. - Contributed by Karl Wright - -* [HTTPCLIENT-1266] NTLM engine refactoring and compatibility improvements. - Contributed by Karl Wright - -* [HTTPCLIENT-1263] BrowserCompatSpec: attribute values containing spaces or special characters - should be enclosed with quotes marks for version 1 cookies. - Contributed by Francois-Xavier Bonnet - -* [HTTPCLIENT-1263] CachingHttpClient fails to release connections back to the connection - manager for some type of HTTP response messages when used together with DecompressingHttpClient. - Contributed by Francois-Xavier Bonnet - -* [HTTPCLIENT-1258] Fixed NullPointerException in NTLMEngineImpl caused by null NT domain - attribute. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1254] Redirect with underscore in hostname causes ProtocolException. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1255] AbstractVerifier incorrectly parses certificate CN containing wildcard. - Contributed by Oleg Kalnichevski - - - -Release 4.2.2 -------------------- - -HttpClient 4.2.2 (GA) is a bug fix release that addresses a number of issues reported since -release 4.2.1. - -Users of HttpClient 4.2 are advised to upgrade. - -Changelog -------------------- - -* [HTTPCLIENT-1248] Default and lax redirect strategies should not convert requests redirected - with 307 status to GET method. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1215] BasicAuthCache does not take default ports into consideration when - looking up cached authentication details by HttpHost key. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1241] (regression) Preemptive BASIC authentication failure should be considered - final and no further attempts to re-authenticate using the same credentials should be made. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1229] Fixed NPE in BasicClientConnectionManager that can be triggered by releasing - connection after the connection manager has already been shut down. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1227] Date parsing in DateUtils made more efficient. - Contributed by Patrick Linskey - -* [HTTPCLIENT-1224] (regression) NTLM auth not retried after a redirect over a non-persistent - connection. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1223] Cache could be more aggressive on cache invalidations - from Content-Location. Contributed by Jon Moore . - Contributed by Jon Moore - -* [HTTPCLIENT-1217] AutoRetryHttpClient does not release connection used by the previous response - when request is retried - Contributed by Oleg Kalnichevski - - -Release 4.2.1 -------------------- - -HttpClient 4.2.1 (GA) is a bug fix release that addresses a number of issues reported since -release 4.2. - -Users of HttpClient 4.2 are advised to upgrade. - -Changelog -------------------- - -* [HTTPCLIENT-1209] Redirect URIs are now normalized. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1202] ResponseCachingPolicy should honor explicit cache-control - directives for other status codes - Contributed by Jon Moore - -* [HTTPCLIENT-1199] DecompressingHttpClient strips content from entity enclosing requests - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1198] HttpHost is not set in HttpContext in CachingHttpClient. - Contributed by Jon Moore - -* [HTTPCLIENT-1200] DecompressingHttpClient fails to generate correct HttpHost context attribute. - Contributed by Guillaume Castagnino - -* [HTTPCLIENT-1192] URIBuilder encodes query parameters twice. - Contributed by Oleg Kalnichevski and Sebastian Bazley . - -* [HTTPCLIENT-1196] Fixed NPE in UrlEncodedFormEntity constructor thrown if charset is null. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1193] Fixed regression in the route tracking logic of the default connection manager - causing cross-site redirect failures. - Contributed by Oleg Kalnichevski - -Release 4.2 -------------------- - -This is the first stable (GA) release of HttpClient 4.2. The most notable enhancements included -in this release are: - -* New facade API for HttpClient based on the concept of a fluent interface. The fluent API exposes - only the most fundamental functions of HttpClient and is intended for relatively simple use cases - that do not require the full flexibility of HttpClient. However, the fluent API almost fully - relieves the users from having to deal with connection management and resource deallocation. - -* Redesigned and rewritten connection management code. - -* Enhanced HTTP authentication API that enables HttpClient to handle more complex authentication - scenarios. HttpClient 4.2 is now capable of making use of multiple authentication challenges - and retry authentication with a fall-back scheme in case the primary one fails. This can be - important for compatibility with Microsoft products that are often configured to use - SPNEGO/Kerberos as the preferred authentication scheme. - - -Changelog -------------------- - -* [HTTPCLIENT-1187] If a revalidation response is deemed too old CachingHttpClient fails to - consume its content resulting in a connection leak. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1186] State of newly created connections in the connection pool is not always - correctly updated potentially allowing those connections to be leased to users with a different - security context. - Contributed by Ralf Poehlmann - -* [HTTPCLIENT-1179] Upgraded Commons Codec dependency to version 1.6 - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1177] always remove fragments from request URIs - Contributed by Oleg Kalnichevski - -Incompatible changes --------------------- -[Compared to release version 4.1.3] - -The following fields have been deprecated for some time now and have been deleted: - -org.apache.http.client.params.ClientPNames#CONNECTION_MANAGER_FACTORY -org.apache.http.impl.cookie.BrowserCompatSpec#DATE_PATTERNS - -The following methods have been deprecated for some time now and have been deleted: - -org.apache.http.client.params.ClientParamBean#setConnectionManagerFactory(org.apache.http.conn.ClientConnectionManagerFactory) -org.apache.http.client.protocol.ClientContextConfigurer#setAuthSchemePref(java.util.List) -org.apache.http.entity.mime.content.FileBody#writeTo(java.io.OutputStream, int) -org.apache.http.entity.mime.content.InputStreamBody#writeTo(java.io.OutputStream, int) -org.apache.http.entity.mime.content.StringBody#writeTo(java.io.OutputStream, int) - -The following classes have been deprecated for some while now and have been deleted: - -org.apache.http.impl.conn.tsccm.RefQueueHandler -org.apache.http.impl.conn.tsccm.AbstractConnPool no longer implements interface org.apache.http.impl.conn.tsccm.RefQueueHandler -org.apache.http.impl.conn.tsccm.ConnPoolByRoute no longer implements interface org.apache.http.impl.conn.tsccm.RefQueueHandler -org.apache.http.impl.conn.tsccm.RefQueueWorker - - - -Release 4.2 BETA1 -------------------- - -This is the first BETA release of HttpClient 4.2. This release completes development of several -notable enhancements in HttpClient: - -* New facade API for HttpClient based on the concept of a fluent interface. The fluent API exposes - only the most fundamental functions of HttpClient and is intended for relatively simple use cases - that do not require the full flexibility of HttpClient. However, the fluent API almost fully - relieves the users from having to deal with connection management and resource deallocation. - -* Redesigned and rewritten connection management code. As of release 4.2 HttpClient will be using - pooling connection manager per default. - -* Enhanced HTTP authentication API that enables HttpClient to handle more complex authentication - scenarios. HttpClient 4.2 is now capable of making use of multiple authentication challenges - and retry authentication with a fall-back scheme in case the primary one fails. This can be - important for compatibility with Microsoft products that are often configured to use - SPNEGO/Kerberos as the preferred authentication scheme. - - -Changelog -------------------- - -* [HTTPCLIENT-1164] Compressed entities are not being cached properly. - Contributed by Jon Moore . - -* [HTTPCLIENT-1154] MemcachedHttpCacheStorage should allow client to - specify custom prefix string for keys. - Contributed by Jon Moore . - -* [HTTPCLIENT-1153] MemcachedHttpCacheStorage uses URL as cache key; - shouldn't due to fixed maximum-length memcached keys. - Contributed by Jon Moore . - -* [HTTPCLIENT-1157] MemcachedHttpCacheStroage should throw IOExceptions - instead of RuntimeExceptions. - Contributed by James Miller . - -* [HTTPCLIENT-1152] MemcachedHttpCacheStorage should verify class of - returned object before casting. - Contributed by Rajika Kumarasiri . - -* [HTTPCLIENT-1155] CachingHttpClient fails to ensure that the response content gets fully consumed - when using a ResponseHandler, which can potentially lead to connection leaks. - Contributed by James Miller - -* [HTTPCLIENT-1147] When HttpClient-Cache cannot open cache file, should act like miss. - Contributed by Joe Campbell - -* [HTTPCLIENT-1137] Values for the Via header are cached and reused by httpclient-cache. - Contributed by Alin Vasile - -* [HTTPCLIENT-1142] Infinite loop on NTLM authentication failure. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1143] CachingHttpClient leaks connections with stale-if-error. - Contributed by James Miller - -Release 4.2 ALPHA1 -------------------- - -This is the first ALPHA release of HttpClient 4.2. The 4.2 branch enhances HttpClient in several -key areas and includes several notable features and improvements: - -* New facade API for HttpClient based on the concept of a fluent interface. The fluent API exposes - only the most fundamental functions of HttpClient and is intended for relatively simple use cases - that do not require the full flexibility of HttpClient. However, the fluent API almost fully - relieves the users from having to deal with connection management and resource deallocation. - -* Redesigned and rewritten connection management code. As of release 4.2 HttpClient will be using - pooling connection manager per default. - -* Enhanced HTTP authentication API that enables HttpClient to handle more complex authentication - scenarios. HttpClient 4.2 is now capable of making use of multiple authentication challenges - and retry authentication with a fall-back scheme in case the primary one fails. This can be - important for compatibility with Microsoft products that are often configured to use - SPNEGO/Kerberos as the preferred authentication scheme. - -Please note that new features included in this release are still considered experimental and -their API may change in the future ALPHA releases. - -Changelog -------------------- - -* [HTTPCLIENT-1128] SystemDefaultHttpClient (HttpClient implementation initialized using system - properties). - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1135] RandomAccessFile mode 'w' used by HttpClientCache is not valid. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1131] HttpClient to authenticate preemptively using BASIC scheme if a userinfo - attribute is specified in the request URI. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1134] make BasicResponseHandler consume response content in case of an unsuccessful - result (status code >= 300). - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1132] ProxyClient implementation. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1127] fixed dead-lock between SingleClientConnManager and AbstractPooledConnAdapter. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1107] Auth framework redesign. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1116] ResponseCachingPolicy uses integers for sizes - Contributed by Greg Bowyer - -* [HTTPCLIENT-1123] Support for pluggable DNS resolvers. - Contributed by Alin Vasile - -* [HTTPCLIENT-1120] DefaultHttpRequestRetryHandler#retryRequest should not retry aborted requests. - Contributed by Alin Vasile - -* Support for auth-int qop (quality of protection) option in Digest auth scheme. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1076] Fluent facade API (Google summer of code 2011 project). - Contributed by Xu Lilu - -* UriBuilder implementation. - Contributed by Xu Lilu - -* Redesign of connection management classes based on new pooling components from HttpCore. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1111] Added #prepareSocket method to SSLSocketFactory. - Contributed by Pasi Eronen - -* Added #reset() and #releaseConnection() methods to HttpRequestBase. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1105] AutoRetryHttpClient: built-in way to do auto-retry for certain status codes. - Contributed by Dan Checkoway - -* [HTTPCLIENT-1094] Digest auth scheme refactoring. - Contributed by Oleg Kalnichevski - -* Lax implementation of RedirectStrategy. - Contributed by Bartosz Firyn - -* [HTTPCLIENT-1044] HttpRequestRetryHandler implementation compliant with the definition of - idempotent methods given in the RFC 2616. - Contributed by Oleg Kalnichevski - - -Release 4.1.2 -------------------- - -The HttpClient 4.1.2 is a bug fix release that addresses a number of non-critical issues reported -since release 4.1.1. - -* [HTTPCLIENT-1100] Missing Content-Length header makes cached entry invalid - Contributed by Bart Robeyns - -* [HTTPCLIENT-1098] Avoid expensive reverse DNS lookup on connect timeout exception. - Contributed by Thomas Boettcher - -* [HTTPCLIENT-1097] BrowserCompatHostnameVerifier and StrictHostnameVerifier should handle - wildcards in SSL certificates better. - Contributed by Sebastian Bazley - -* [HTTPCLIENT-1092] If ClientPNames.VIRTUAL_HOST does not provide the port, derive it from the - current request. - Contributed by Sebastian Bazley - -* [HTTPCLIENT-1087] NTLM proxy authentication fails on retry if the underlying connection is closed - as a result of a target authentication failure. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1079] Fixed Kerberos cross-realm support - Contributed by Michael Osipov <1983-01-06 at gmx.net> - -* [HTTPCLIENT-1078] Decompressing entities (DeflateDecompressingEntity, GzipDecompressingEntity) - do not close content stream in #writeTo() method. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1075] Decompressing entities (DeflateDecompressingEntity, GzipDecompressingEntity) - do not correctly handle content streaming. - Contributed by James Abley - -* [HTTPCLIENT-1051] Avoid reverse DNS lookups when opening SSL connections by IP address. - Contributed by Oleg Kalnichevski - - -Release 4.1.1 -------------------- - -HttpClient v4.1.1 is a bug fix release that addresses a number of issues reported since -release 4.1, including one critical security issue (HTTPCLIENT-1061). All users of HttpClient 4.0.x -and 4.1 are strongly encouraged to upgrade. - -* [HTTPCLIENT-1069] HttpHostConnectException not correctly retried for direct and non-tunnelled - proxy connections. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1066] Changed the way URIUtils#rewriteURI handles multiple consecutive slashes in the - URI path component: multiple leading slashes will be replaced by one slash in order to avoid - confusion with the authority component. The remaining content of the path will not be modified. - (also see HTTPCLIENT-929). - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1061] Fixed critical bug causing Proxy-Authorization header to be sent to the target - host when tunneling requests through a proxy server that requires authentication. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1056] Fixed bug causing the RequestAuthCache protocol interceptor to generate - an invalid AuthScope instance when looking up user credentials for preemptive authentication. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1053] Fixed the way DigestScheme generates nonce-count values. - Contributed by Oleg Kalnichevski - - -Release 4.1 -------------------- - -The HttpClient 4.1 release builds upon the stable foundation laid by HttpClient 4.0 and adds several -functional improvements and popular features. - -* Response caching conditionally compliant with HTTP/1.1 specification (full compliance with - MUST requirements, partial compliance with SHOULD requirements) - -* Full support for NTLMv1, NTLMv2, and NTLM2 Session authentication. The NTLM protocol code - was kindly contributed by the Lucene Connector Framework project. - -* Support for SPNEGO/Kerberos authentication. - -* Persistence of authentication data between request executions within the same execution context. - -* Support for preemptive authentication for BASIC and DIGEST schemes. - -* Support for transparent content encoding. Please note transparent content encoding is not - enabled per default in order to avoid conflicts with already existing custom content encoding - solutions. - -* Mechanism to bypass the standard certificate trust verification (useful when dealing with - self-signed certificates). - -* Simplified configuration for connection managers. - -* Transparent support for host multihoming. - -IMPORTANT: please note that the HttpClient 3.x branch is now officially END OF LIFE and is no longer -maintained and supported by the Apache HttpComponents project. - -Changelog -------------------- -* The public API for the caching module had a minor change between 4.1-beta and 4.1-GA to the - HttpCacheEntry class - the deprecated public Set getVariantURIs() method and constructor - public HttpCacheEntry(Date requestDate, Date responseDate, - StatusLine statusLine, Header[] responseHeaders, - Resource resource, Set variants) - were both removed. This will not affect you unless you are implementing new storage backends - that use the deprecated code and/or are implementing custom serializers for cache entries. - -* Changed Browser-Compatibility and Best-Match cookie policies to emulate the behaviour of FireFox - more closely when parsing Netscape style cookies. Comma will no longer be treated as a header - element separator if Set-Cookie does not contain a Version attribute mandated by the - RFC2109 / RFC 2965 cookie specifications. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1036] StringBody has incorrect default for characterset. (Default changed - to US-ASCII) - Contributed by Sebastian Bazley - -* [HTTPCLIENT-975] Support stale-if-error and stale-while-revalidate extension directive (RFC5861). - Contributed by Mohammed Azeem Uddin , - Michajlo Matijkiw , and - Matthew Hawthorne . - -* [HTTPCLIENT-1033] HttpRoute.equals(Object o) is quite inefficient, as it does not take full - advantage of shortcut logic. - Contributed by Sebastian Bazley - -* [HTTPCLIENT-1030] Implement "ignoreCookies" CookieSpec - Contributed by Sebastian Bazley - -Release 4.1 BETA1 -------------------- - -HttpClient 4.1 BETA1 finalizes the 4.1 API and brings a number of major improvements to the HTTP -caching module. This release also adds full support for NTLMv1, NTLMv2, and NTLM2 Session -authentication. The NTLM protocol code was kindly contributed by the Lucene Connector Framework -project. - -Changelog -------------------- -* [HTTPCLIENT-1015] Support only-if-cached directive. - Contributed by Michajlo Matijkiw - -* [HTTPCLIENT-990] Allow heuristic freshness caching. - Contributed by Michajlo Matijkiw - -* [HTTPCLIENT-919] Support for NTLMv1, NTLMv2, and NTLM2 Session authentication. - Contributed by Karl Wright - -* [HTTPCLIENT-1008] Send all variants' ETags on "variant miss". - Contributed by Michajlo Matijkiw and - Mohammed Azeem Uddin - -* [HTTPCLIENT-1011] Handling of IOExceptions thrown by cache components. - Contributed by Jonathan Moore - -* [HTTPCLIENT-1003] Handle conditional requests in cache. - Contributed by Michajlo Matijkiw and - Mohammed Azeem Uddin - -* [HTTPCLIENT-1002] Stale connection check fails if wire logging is on. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-1000] Maximum connection lifetimes settings for ThreadSafeClientConnManager. - Contributed by Michajlo Matijkiw - -* [HTTPCLIENT-960] HttpMultipart doesn't generate Content-Type header for binary parts in - BROWSER_COMPATIBLE mode. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-998] Cache should use both Last-Modified and ETag for validations when available. - Contributed by Jonathan Moore - -* [HTTPCLIENT-997] Cache module should handle out-of-order validations properly and unconditionally - refresh. - Contributed by Jonathan Moore - -* [HTTPCLIENT-994] Cache does not allow client to override origin-specified freshness using - max-stale. - Contributed by Jonathan Moore - -* [HTTPCLIENT-995] Cache returns cached responses even if validators not consistent with all - conditional headers. - Contributed by Jonathan Moore - -* [HTTPCLIENT-977] Memcached implementation for HttpCache. - Contributed by Mohammed Azeem Uddin - -* [HTTPCLIENT-992] cache should not generate stale responses to requests explicitly requesting - first-hand or fresh ones. - Contributed by Jonathan Moore - -* [HTTPCLIENT-991] cache module produces improperly formatted Warning header when revalidation - fails. - Contributed by Jonathan Moore - -* [HTTPCLIENT-989] DefaultHttpRequestRetryHandler no longer retries non-idempotent http methods - if NoHttpResponseException is thrown. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-988] Cache module should strip 'Content-Encoding: identity' from responses - Contributed by Jonathan Moore - -* [HTTPCLIENT-987] cache module does not recognize equivalent URIs. - Contributed by Jonathan Moore - -* [HTTPCLIENT-986] cache module does not completely handle upstream Warning headers correctly - Contributed by Jonathan Moore - -* [HTTPCLIENT-985] cache module should populate Via header to capture upstream and downstream protocols - Contributed by Jonathan Moore - -* [HTTPCLIENT-984] Additional conditional compliance tests for the caching module for - Content-Encoding, Content-Location, Date, Expires, Server, Transfer-Encoding, and Vary headers. - Contributed by Jonathan Moore - -* [HTTPCLIENT-978] HTTP cache update exception handling - Contributed by Michajlo Matijkiw - -* [HTTPCLIENT-981] CachingHttpClient returns a 411 respones when executing a POST (HttpPost) - request. - Contributed by Joe Campbell - -* [HTTPCLIENT-980] CachingHttpClient returns a 503 response when the backend HttpClient produces - an IOException. - Contributed by Jonathan Moore - -* [HTTPCLIENT-978] Ehcache based HTTP cache implementation - Contributed by Michajlo Matijkiw - -* [HTTPCLIENT-967] support for non-shared (private) caches - Contributed by Jonathan Moore - -* [HTTPCLIENT-969] BasicCookieStore#getCookies() to return a copy of Cookie list - Contributed by David Smiley - -* [HTTPCLIENT-965] Fixed problem with cache not honoring must-revalidate or - proxy-revalidate Cache-Control directives. - Contributed by Jonathan Moore - -* [HTTPCLIENT-964] 'no-cache' directives with field names are no longer transmitted - downstream. - Contributed by Jonathan Moore - -* [HTTPCLIENT-963] Fixed handling of 'Cache-Control: no-store' on requests. - Contributed by Jonathan Moore - -* [HTTPCLIENT-962] Fixed handling of Authorization headers in shared cache mode. - Contributed by Jonathan Moore - -* [HTTPCLIENT-961] Not all applicable URIs are invalidated on PUT/POST/DELETEs - that pass through client cache. - Contributed by Jonathan Moore - -* [HTTPCLIENT-958] Client cache no longer allows incomplete responses to be - passed on to the client. - Contributed by Jonathan Moore - -* [HTTPCLIENT-951] Non-repeatable entity enclosing requests are not correctly - retried when 'expect-continue' handshake is active. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-948] In rare circumstances the idle connection handling code - can leave closed connections in a inconsistent state. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-953] IllegalStateException thrown by RouteSpecificPool. - Contributed by Guillaume - -* [HTTPCLIENT-952] Trust store parameter is ignored by SSLSocketFactory - (affects version 4.1-alpha2 only) - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-937] CacheEntry made immutable; now uses immutable HttpEntity - to store cached content. - Contributed by David Mays and - Oleg Kalnichevski - -Release 4.1 ALPHA2 -------------------- - -HttpClient 4.1 ALPHA2 fixes a number of non-severe bugs discovered since -the last release and introduces support for two frequently requested features: - -* HTTP/1.1 response caching - -* transparent support for host multihoming - -* a mechanism to bypass the standard certificate trust verification -(useful when dealing with self-signed certificates) - -Compatibility notes -------------------- -(1) Please note the HTTP caching module is still considered experimental and -its API may change significantly in the future releases. - -(2) This release eliminates Mime4J as a dependency for the HttpMime module. -HttpMime is no longer binary compatible with the previous releases. -Full API and binary compatibility between minor versions of HttpMime will be -maintained as of 4.1 GA release. - -Changelog -------------------- - -* [HTTPCLIENT-936] Fixed bug causing NPE or an infinite loop in - the authentication code in case of a SPNEGO authentication failure. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-427] HTTP caching support - Contributed by Joe Campbell, David Cleaver, David Mays, Jon Moore, Brad Spenla - -* Dropped dependency on Mime4j for HttpMime. - Contributed by Oleg Kalnichevski - -* Extended SSLSocketFactory with a mechanism to bypass the standard certificate - trust verification (primarily to simplify dealing with self-signed - certificates) - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-898] Improved support for host multihoming - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-916] UsernamePasswordCredentials, NTUserPrincipal, - BasicClientCookie, BasicClientCookie2 and BasicCookieStore made Serializable. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-914] Upgraded Commons Codec dependency to version 1.4 - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-903] Use ConcurrentHashMap instead of [Linked]HashMap for - thread-safety. Improve performance of AuthSchemeRegistry, CookieSpecRegistry - and SchemeRegistry classes. - Contributed by Sebastian Bazley - -* [HTTPCLIENT-902] HttpRequestRetryHandler not called on I/O exceptions - thrown when opening a new connection. - Contributed by Olivier Lamy and - Oleg Kalnichevski - -Release 4.1 ALPHA1 -------------------- - -HttpClient 4.1 ALPHA1 builds on the stable 4.0 release and adds several -functionality improvements and new features. - -* Simplified configuration of connection managers. - -* Persistence of authentication data between request executions within - the same execution context. - -* Support for SPNEGO/Kerberos authentication scheme - -* Support for transparent content encoding. Please note transparent content - encoding is not enabled per default in order to avoid conflicts with - already existing custom content encoding solutions. - -* 5 to 10% performance increase due to elimination of unnecessary Log object - lookups by short-lived components. - -Please note all methods and classes added in this release and marked as -4.1 are API unstable and can change in the future 4.1 ALPHA releases. - -Changelog -------------------- - -* [HTTPCLIENT-889] 'expect: continue' handshake disabled per default. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-862] Extended client's redirect handling interface to allow - control of the content of the redirect. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-872] HttpClient can now persist authentication data between request - executions as long as they share the same execution context. It has also become - much easier to make HttpClient authenticate preemptively by pre-populating - authentication data cache. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-883] SO_TIMEOUT is not reset on persistent (re-used) connections. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-832] Distinguish cookie format errors from violations of - restrictions imposed by a cookie specification. In the latter case - CookieRestrictionViolationException will be thrown. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-523] Support for SPNEGO authentication scheme. - Contributed by Matthew Stevenson - -* Simplified configuration of connection managers. Total connection maximum - and maximum connection per route limits can be set using methods of - the class instead of HTTP parameters. - Contributed by Oleg Kalnichevski - -* Added parameters to define the order of preference for supported auth - schemes for target host and proxy authentication. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-875] DefaultClientConnectionOperator#openConnection doesn't - update the connection state if the connection socket changed after - the call to SocketFactory#connectSocket(). - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-834] Transparent content encoding support. - Contributed by James Abley - -Release 4.0.1 -------------------- - -This is a bug fix release that addresses a number of issues discovered since -the previous stable release. None of the fixed bugs is considered critical. -Most notably this release eliminates eliminates dependency on JCIP annotations. - -This release is also expected to improve performance by 5 to 10% due to -elimination of unnecessary Log object lookups by short-lived components. - -Changelog -------------------- - -* [HTTPCLIENT-895] Eliminated Log lookups in short lived objects impairing - performance. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-885] URLEncodedUtils now correctly parses form-url-encoded - entities that specify a charset. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-884] UrlEncodedFormEntity now sets charset on the Content-Type - header. - Contributed by Jared Jacobs - -* [HTTPCLIENT-883] SO_TIMEOUT is not reset on persistent (re-used) connections. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-882] Auth state is now correctly updated if a successful NTLM - authentication results in a redirect. This is a minor bug as HttpClient - manages to recover from the problem automatically. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-881] Fixed race condition in AbstractClientConnAdapter that makes - it possible for an aborted connection to be returned to the pool. - Contributed by Tim Boemker and - Oleg Kalnichevski - -* [HTTPCLIENT-866] Removed dependency on jcip-annotations.jar. - Contributed by Oleg Kalnichevski - and Sebastian Bazley - - -Release 4.0 -------------------- - -HttpClient 4.0 represents a complete, ground-up redesign and almost a complete -rewrite of the HttpClient 3.x codeline. This release finally addresses several -design flaws that existed since the 1.0 release and could not be fixed without -a major code overhaul and breaking API compatibility. - - -Architectural changes ---------------------- - -* Redesign of the HttpClient internals addressing all known major - architectural shortcomings of the 3.x codeline. - -* Cleaner, more flexible and expressive API. - -* More modular structure. - -* Better performance and smaller memory footprint due to a more efficient HTTP - transport based on HttpCore. - -* Implementation of cross-cutting HTTP protocol aspects through protocol - interceptors. - -* Improved connection management, better handling of persistent connections, - support for stateful connections - -* Pluggable redirect and authentication handlers. - -* Improved support for sending requests via a proxy or a chain of proxies - -* More flexible SSL context customization - -* Reduced intermediate garbage in the process of generating HTTP requests - and parsing HTTP responses - - -Important notes -------------------- - -* Future releases of HttpMime module may be binary incompatible with this - release due to possible API changes in Apache Mime4J. Apache Mime4J is - still being actively developed and its API is considered unstable. - -* HttpClient 4.0 is not fully binary compatible with 4.0 BETA1 release. - Some protected variables in connection management class have been - made final in order to help ensure their thread safety: - - org.apache.http.conn.BasicEofSensorWatcher#attemptReuse - org.apache.http.conn.BasicEofSensorWatcher#managedConn - org.apache.http.impl.conn.DefaultClientConnectionOperator#schemeRegistry - org.apache.http.impl.conn.DefaultHttpRoutePlanner#schemeRegistry - org.apache.http.impl.conn.ProxySelectorRoutePlanner#schemeRegistry - org.apache.http.impl.conn.SingleClientConnManager#alwaysShutDown - org.apache.http.impl.conn.SingleClientConnManager#connOperator - org.apache.http.impl.conn.SingleClientConnManager#schemeRegistry - org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager#connOperator - org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager#schemeRegistry - - -Bug fixes since 4.0 BETA2 release -------------------- - -* [HTTPCLIENT-861] URIUtils#resolve is now compatible with all examples given - in RFC 3986. - Contributed by Johannes Koch - -* [HTTPCLIENT-860] HttpClient no longer converts redirects of PUT/POST to GET - for status codes 301, 302, 307, as required by the HTTP spec. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-859] CookieIdentityComparator now takes path attribute into - consideration when comparing cookies. - Contributed by Oleg Kalnichevski - -* HttpClient will no longer send expired cookies back to the origin server. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-856] Proxy NTLM authentication no longer fails on a redirect to - a different host. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-841] Removed automatic connection release using garbage collection - due to a memory leak. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-853] Fixed bug causing invalid cookie origin port to be selected - when the target is accessed on the default port and the connection is - established via a proxy. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-852] Fixed bug causing automatically retried redirects fail with - CircularRedirectException. - Contributed by Oleg Kalnichevski - -* Fixed problem with the default HTTP response parser failing to handle garbage - preceding a valid HTTP response. - Contributed by Oleg Kalnichevski - -* NonRepeatableRequestExceptions now include the cause that the original - request failed. - Contributed by Sam Berlin - -* [HTTPCLIENT-837] Fixed problem with the wire log skipping zero byte values - if read one byte at a time. - Contributed by Kirill Safonov - -* [HTTPCLIENT-823] 'http.conn-manager.max-total' parameter can be adjusted - dynamically. However, the size of existing connection pools per route, - once allocated, will not be adjusted. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-822] Default socket factories to rethrow SocketTimeoutException - as ConnectTimeoutException in case of connect failure due to a time out. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-813] Fixed default port resolution. Invalid ports no longer - get replaced with the default port value. - Contributed by Oleg Kalnichevski - -Release 4.0 beta 2 -------------------- - -BETA2 is a maintenance release, which addresses a number of issues -discovered since the previous release. - -The only significant new feature is an addition of an OSGi compliant -bundle combining HttpClient and HttpMime jars. - -All upstream projects are strongly encouraged to upgrade. - -* Fixed NPE in DefaultRequestDirector thrown when retrying a failed - request over a proxied connection. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-803] Fixed bug in SSL host verifier implementations - causing the SSL certificate to be rejected as invalid if the connection - is established using an IP address. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-806] DefaultHttpMethodRetryHandler will no longer retry - on ConnectExceptions. - Contributed by Oleg Kalnichevski - -* DigestScheme can use an arbitrary digest algorithm requested by the - target server (such as SHA) as long as this algorithm is supported by - the Java runtime. - Contributed by Oleg Kalnichevski - -* Fixed parsing and validation of RFC2109 compliant Set-Cookie headers - by the Best-Match cookie spec. - Contributed by Oleg Kalnichevski - -* Fixed bug that can cause a managed connection to be returned from the - pool in an inconsistent state. - Contributed by Oleg Kalnichevski - - -4.0 Beta 1 -------------------- - -BETA1 release brings yet another round of API enhancements and -improvements in the area of connection management. Among the most notable -ones is the capability to handle stateful connections such as persistent -NTLM connections and private key authenticated SSL connections. - -This is the first API stable release of HttpClient 4.0. All further -releases in the 4.0 code line will maintain API compatibility with this -release. - -There has been a number of important bug fixes since ALPHA4. All upstream -projects are encouraged to upgrade to the latest release. - -Please note HttpClient currently provides only limited support for NTLM -authentication. For details please see NTLM_SUPPORT.txt. - -------------------- - -Changelog: -------------------- - -* [HTTPCLIENT-790] Protocol interceptors are now correctly invoked when - executing CONNECT methods. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-668] Do not use static loggers. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-781] Respect Keep-Alive header's timeout value. - Contributed by Sam Berlin - -* [HTTPCLIENT-779] Top-level classes (HttpClient, and HttpGet, HttpPut - and similar HttpMethods) throw fewer checked exceptions. - Contributed by Sam Berlin - -* HttpClient will throw an exception if an attempt is made to retry - a request with a non-repeatable request entity. - Contributed by Oleg Kalnichevski - -* Fixed request re-generation logic when retrying a failed request. - Auto-generated headers will no accumulate. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-424] Preemptive authentication no longer limited to BASIC - scheme only. HttpClient can be customized to authenticate preemptively - with DIGEST scheme. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-670] Pluggable hostname resolver. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-719] Clone support for HTTP request and cookie objects. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-776] Fixed concurrency issues with AbstractPoolEntry. - Contributed by Sam Berlin - -* Resolved a long standing problem with HttpClient not taking into account - the user context when pooling / re-using connections. HttpClient now - correctly handles stateful / user specific connections such as persistent - NTLM connections and SSL connections with client side authentication. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-773] Improved handling of the 'expires' attribute by the - 'Best Match' cookie spec. - Contributed by Oleg Kalnichevski - -* Partial NTLM support (requires an external NTLM engine). For details see - NTLM_SUPPORT.txt - Contributed by Oleg Kalnichevski - -* Redesigned local execution context management. - Contributed by Oleg Kalnichevski - --------------------------------------- - -Release 4.0 Alpha 4 -------------------- - -ALPHA4 marks the completion of the overhaul of the connection management -code in HttpClient. All known shortcomings of the old HttpClient 3.x -connection management API have been addressed. - -NTLM authentication remains the only missing major feature in the new -codeline that prevents us from moving awards the API freeze. - -There has been a number of important bug fixes since ALPHA3. All upstream -projects are encouraged to upgrade to the latest release. - -------------------- - -HttpClient 3.x features that have NOT yet been ported: -------------------- - -* NTLM authentication scheme - -------------------- - -Changelog: -------------------- - -* [HTTPCLIENT-765] String.toLowerCase() / toUpperCase() should specify - Locale.ENGLISH - Contributed by Sebastian Bazley - -* [HTTPCLIENT-769] Do not pool connection marked non-reusable. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-763] Fixed problem with AbstractClientConnAdapter#abortConnection() - not releasing the connection if called from the main execution thread while - there is no blocking I/O operation. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-652] Added optional state attribute to managed client connections. - This enables connection managers to correctly handle stateful connections. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-673] Revised max connections per route configuration - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-753] Class Scheme and related classes moved to a separate package - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-757] Improved request wrapping in the DefaultClientRequestDirector. - This also fixed the problem with the default proxy set at the client level - having no effect. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-734] Request abort will unblock the thread waiting for a connection - Contributed by Sam Berlin - -* [HTTPCLIENT-759] Ensure release of connections back to the connection manager - on exceptions. - Contributed by Sam Berlin - -* [HTTPCLIENT-758] Fixed the use of generics in AbstractHttpClient - #removeRequestInterceptorByClass and #removeResponseInterceptorByClass - Contributed by Johannes Koch - -* [HTTPCLIENT-749] HttpParams beans - Contributed by Stojce Dimski - -* [HTTPCLIENT-755] Workaround for known bugs in java.net.URI.resolve() - Bug ID: 4708535 - Contributed by Johannes Koch - --------------------------------------- - -Release 4.0 Alpha 3 -------------------- - -ALPHA3 release brings another round of API refinements and improvements in -functionality. As of this release HttpClient requires Java 5 compatible -runtime environment and takes full advantage of generics and new concurrency -primitives. - -This release also introduces new default cookie policy that selects a cookie -specification depending on the format of cookies sent by the target host. -It is no longer necessary to know beforehand what kind of HTTP cookie support -the target host provides. HttpClient is now able to pick up either a lenient -or a strict cookie policy depending on the compliance level of the target host. - -Another notable improvement is a completely reworked support for multipart -entities based on Apache mime4j library. - -------------------- - -HttpClient 3.x features that have NOT yet been ported: -------------------- - -* NTLM authentication scheme - -------------------- - -Changelog: -------------------- - -* [HTTPCLIENT-742] common interface for HttpRoute and RouteTracker - Contributed by Roland Weber - -* [HTTPCLIENT-741] Fixed concurrency issues in AbstractClientConnAdapter. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-726] testcase for spurious wakeups in ThreadSafeClientConnManager - Contributed by Roland Weber - -* [HTTPCLIENT-643] Automatic connect fail-over for multi-home remote servers. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-735] unsetting of DEFAULT_PROXY and FORCED_ROUTE in hierarchies - Contributed by Roland Weber - -* [HTTPCLIENT-723] route planner based on java.net.ProxySelector - Contributed by Roland Weber - -* [HTTPCLIENT-740] don't start connection GC thread in pool constructor - Contributed by Roland Weber - -* [HTTPCLIENT-736] route planners use SchemeRegistry instead of ConnManager - Contributed by Roland Weber - -* [HTTPCLIENT-730] Fixed rewriting of URIs containing escaped characters - Contributed by Sam Berlin and - Oleg Kalnichevski - -* [HTTPCLIENT-667] Added 'Meta' cookie policy that selects a cookie - specification depending on the format of the cookie(s). - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-729] Move HttpRoute and related classes to routing package. - Contributed by Roland Weber - -* [HTTPCLIENT-725] Use TimeUnit arguments for timeouts in connection manager. - Contributed by Roland Weber - -* [HTTPCLIENT-677] Connection manager no longer uses Thread.interrupt(). - Contributed by Roland Weber - -* [HTTPCLIENT-716] Allow application-defined routes. - Contributed by Roland Weber - -* [HTTPCLIENT-712] Improve HttpRoute API - Contributed by Roland Weber - -* [HTTPCLIENT-711] Bad route computed for redirected requests - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-715] Remove RoutedRequest from API - Contributed by Roland Weber - -* [HTTPCLIENT-705] Fixed incorrect handling of URIs with null path component. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-688] HttpOptions#getAllowedMethods can now handle multiple - Allow headers. - Contributed by Andrea Selva - --------------------------------------- - -Release 4.0 Alpha 2 -------------------- - -ALPHA2 release is another milestone in the redesign of HttpClient. It includes -a number of improvements since ALPHA1, among which are improved connection -pooling, support for proxy chains, redesigned HTTP state and authentication -credentials management API, improved RFC 2965 cookie specification. - -------------------- - -HttpClient 3.x features that have NOT yet been ported -------------------- -* NTLM authentication scheme - -* Support for multipart MIME coded entities - -------------------- - -Changelog -------------------- - -* [HTTPCLIENT-698] Resolve non-absolute redirect URIs relative to - the request URI - Contributed by Johannes Koch - -* [HTTPCLIENT-697] Throw a more intelligible exception when connection - to a remote host cannot be established. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-689] Caching of SimpleDateFormat in DateUtils - Contributed by Daniel Müller - -* [HTTPCLIENT-689] stackable parameters in AbstractHttpClient - Contributed by Roland Weber - -* [HTTPCLIENT-477] Use distinct instances of the authentication handler - interface for authentication with target and proxy hosts - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-690] ManagedClientConnection provides access to SSLSession - Contributed by Roland Weber - -* [HTTPCLIENT-692] ClientConnectionManager throws InterruptedException - Contributed by Roland Weber - -* [HTTPCORE-116] moved parameter names to interfaces - Contributed by Roland Weber - -* [HTTPCLIENT-649] support for proxy chains in HttpConn - Contributed by Roland Weber - -* [HTTPCLIENT-636] refactor ThreadSafeClientConnManager in separate package - Contributed by Roland Weber - -* [HTTPCLIENT-669] new HttpRoutePlanner interface and implementation - Contributed by Andrea Selva - -* [HTTPCLIENT-653] detached connection wrapper no longer prevents - garbage collection of ThreadSafeClientConnManager - Contributed by Roland Weber - -* [HTTPCLIENT-674] use org.apache.http.util.VersionInfo instead of a local one - Contributed by Roland Weber - -* [HTTPCLIENT-666] Replaced HttpState with CredentialsProvier and CookieStore interfaces - Contributed by Oleg Kalnichevski - -* [HTTPCORE-100] revised HttpContext hierarchy - Contributed by Roland Weber - -* [HTTPCLIENT-618] eliminate class HostConfiguration - Contributed by Roland Weber - -* [HTTPCLIENT-672] re-sync with API changes in core alpha6-SNAPSHOT - Contributed by Roland Weber - --------------------------------------- - -Release 4.0 Alpha 1 -------------------- - -HttpClient 4.0 represents a complete, ground-up redesign and almost a complete -rewrite of the HttpClient 3.x codeline. This release finally addresses several -design flaws that existed since the 1.0 release and could not be fixed without -a major code overhaul and breaking API compatibility. - -The HttpClient 4.0 API is still very experimental and is bound to change -during the course of the ALPHA development phase. Several important features -have not yet been ported to the new API. - -Architectural changes ---------------------- - -* Redesign of the HttpClient internals addressing all known - major architectural shortcomings of the 3.x codeline - -* Cleaner, more flexible and expressive API - -* Better performance and smaller memory footprint due to a more - efficient HTTP transport based on HttpCore. HttpClient 4.0 is - expected to be 10% to 25% faster than HttpClient 3.x codeline - -* More modular structure - -* Pluggable redirect and authentication handlers - -* Support for protocol incerceptors - -* Improved connection management - -* Improved support for sending requests via a proxy or a chain of - proxies - -* Improved handling redirects of entity enclosing requests - -* More flexible SSL context customization - -* Reduced intermediate garbage in the process of - generating HTTP requests and parsing HTTP responses - -------------------- - -HttpClient 3.x features that have NOT yet been ported -------------------- -* NTLM authentication scheme - -* RFC2965 cookie policy (Cookie2) - -* Support for multipart MIME coded entities - -------------------- - -Changelog -------------------- - -The following is a list of contributions tracked in JIRA. -Note that this is not a complete list of contributions or changes. -Since the API was redesigned completely, tracking everything outside -of the source code repository would have been too burdensome. - -* [HTTPCLIENT-655] User-Agent string no longer violates RFC - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-541] Virtual host API redesign - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-614] Allow for different strategies when checking - CN of x509 certificates - Contributed by Julius Davies - -* [HTTPCLIENT-136] Fixed inadequate proxy support - Long standing architectural problem. Issue opened on 19/Dec/2002. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-63] Support for pluggable redirect and authentication handlers - Long standing architectural problem. Issue opened on 15/Jul/2002. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-245] Fixed redirect handling. HttpClient can now automatically - handle redirects of entity enclosing requests. - Long standing architectural problem. Issue opened on 14/Jul/2003. - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-613] HTTPS connections now verify CN of x509 certificates - Contributed by Julius Davies - -* [HTTPCLIENT-497] Wire/header logger names consistent with class loggers - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-484] AuthSSLProtocolSocketFactory in the main distribution - Contributed by Oleg Kalnichevski - -* [HTTPCLIENT-589] Do not consume the remaining response content if - the connection is to be closed - Contributed by Roland Weber - -* [HTTPCLIENT-475] Support for unconnected sockets. HTTP requests can now be - aborted while network socket is still being connected. - Contributed by Roland Weber - diff --git a/httpcomponents-client-4.2.3/lib/commons-codec-1.6.jar b/lib/commons-codec-1.6.jar similarity index 100% rename from httpcomponents-client-4.2.3/lib/commons-codec-1.6.jar rename to lib/commons-codec-1.6.jar diff --git a/httpcomponents-client-4.2.3/lib/commons-logging-1.1.1.jar b/lib/commons-logging-1.1.1.jar similarity index 100% rename from httpcomponents-client-4.2.3/lib/commons-logging-1.1.1.jar rename to lib/commons-logging-1.1.1.jar diff --git a/httpcomponents-client-4.2.3/lib/fluent-hc-4.2.3.jar b/lib/fluent-hc-4.2.3.jar similarity index 100% rename from httpcomponents-client-4.2.3/lib/fluent-hc-4.2.3.jar rename to lib/fluent-hc-4.2.3.jar diff --git a/httpcomponents-client-4.2.3/lib/httpclient-4.2.3.jar b/lib/httpclient-4.2.3.jar similarity index 100% rename from httpcomponents-client-4.2.3/lib/httpclient-4.2.3.jar rename to lib/httpclient-4.2.3.jar diff --git a/httpcomponents-client-4.2.3/lib/httpclient-cache-4.2.3.jar b/lib/httpclient-cache-4.2.3.jar similarity index 100% rename from httpcomponents-client-4.2.3/lib/httpclient-cache-4.2.3.jar rename to lib/httpclient-cache-4.2.3.jar diff --git a/httpcomponents-client-4.2.3/lib/httpcore-4.2.2.jar b/lib/httpcore-4.2.2.jar similarity index 100% rename from httpcomponents-client-4.2.3/lib/httpcore-4.2.2.jar rename to lib/httpcore-4.2.2.jar diff --git a/httpcomponents-client-4.2.3/lib/httpmime-4.2.3.jar b/lib/httpmime-4.2.3.jar similarity index 100% rename from httpcomponents-client-4.2.3/lib/httpmime-4.2.3.jar rename to lib/httpmime-4.2.3.jar diff --git a/action/ActionRegistry.java b/src/action/ActionRegistry.java similarity index 90% rename from action/ActionRegistry.java rename to src/action/ActionRegistry.java index 8c1d98d..29779b3 100644 --- a/action/ActionRegistry.java +++ b/src/action/ActionRegistry.java @@ -17,6 +17,8 @@ public static enum Action { LV_UP, PFB_GOOD, RECV_PFB_GOOD, - USE + USE, + GET_REWARD_BOX, + PARTY_RANK } } diff --git a/action/AddArea.java b/src/action/AddArea.java similarity index 55% rename from action/AddArea.java rename to src/action/AddArea.java index f5cf9e4..b9e88a7 100644 --- a/action/AddArea.java +++ b/src/action/AddArea.java @@ -14,30 +14,32 @@ import org.w3c.dom.NodeList; import walker.ErrorData; +import walker.Info; import walker.Process; import action.ActionRegistry.Action; public class AddArea { public static final Action Name = Action.ADD_AREA; - - private static final String URL_AREA = "http://web.million-arthurs.com/connect/app/exploration/area?cyt=1"; - + + private static final String URL_AREA = "http://web.million-arthurs.com/connect/app/exploration/area?cyt=1"; + private static byte[] response; - + public static boolean run() throws Exception { response = null; Document doc; try { - response = Process.network.ConnectToServer(URL_AREA, new ArrayList(), false); + response = Process.network.ConnectToServer(URL_AREA, + new ArrayList(), false); } catch (Exception ex) { - //if (ex.getMessage().equals("302")) + // if (ex.getMessage().equals("302")) // 上面的是为了截获里图跳转 ErrorData.currentDataType = ErrorData.DataType.text; ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; ErrorData.text = ex.getMessage(); throw ex; } - + try { doc = Process.ParseXMLBytes(response); } catch (Exception ex) { @@ -46,44 +48,69 @@ public static boolean run() throws Exception { ErrorData.bytes = response; throw ex; } - + try { XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { ErrorData.currentErrorType = ErrorData.ErrorType.AreaResponse; ErrorData.currentDataType = ErrorData.DataType.text; - ErrorData.text = xpath.evaluate("/response/header/error/message", doc); + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); return false; } - - int areaCount = ((NodeList)xpath.evaluate("//area_info_list/area_info", doc, XPathConstants.NODESET)).getLength(); - if (areaCount > 0) Process.info.area = new Hashtable(); + + int areaCount = ((NodeList) xpath.evaluate( + "//area_info_list/area_info", doc, XPathConstants.NODESET)) + .getLength(); + if (areaCount > 0) + Process.info.area = new Hashtable(); Area newArea = new Area(); newArea.areaId = -1; - for (int i = areaCount; i > 0; i--){ + for (int i = areaCount; i > 0; i--) { Area a = new Area(); - String p = String.format("//area_info_list/area_info[%d]/",i); - a.areaId = Integer.parseInt(xpath.evaluate(p+"id", doc)); + String p = String.format("//area_info_list/area_info[%d]/", i); + a.areaId = Integer.parseInt(xpath.evaluate(p + "id", doc)); if (Process.info.area.containsKey(a.areaId)) { continue; } else { newArea = a; } - a.areaName = xpath.evaluate(p+"name", doc); - a.exploreProgress = Integer.parseInt(xpath.evaluate(p+"prog_area", doc)); - if (a.areaId > 100000) Process.info.area.put(a.areaId, a); + a.areaType = (a.areaId >= Info.InnerMapNo) ? 1 : 0; + a.areaName = xpath.evaluate(p + "name", doc); + a.exploreProgress = Integer.parseInt(xpath.evaluate(p + + "prog_area", doc)); + if (a.areaId > 100000) + Process.info.area.put(a.areaId, a); } Process.info.AllClear = true; - - if (newArea.areaId != -1) GetFloorInfo.getFloor(newArea); - + + if (newArea.areaId != -1) + GetFloorInfo.getFloor(newArea); + + if (Info.MinAPOnly || Process.info.AllClear) { + if (Info.InnerInstance) { + for (int i : Process.info.floor.keySet()) { + if (Process.info.floor.get(i).innerFlag) { + Process.info.front = Process.info.floor.get(i); + break; + } + } + } else { + for (int i : Process.info.floor.keySet()) { + if (!Process.info.floor.get(i).innerFlag) { + Process.info.front = Process.info.floor.get(i); + break; + } + } + } + } } catch (Exception ex) { if (ErrorData.currentErrorType == ErrorData.ErrorType.none) { throw ex; } } - + return true; } diff --git a/action/Explore.java b/src/action/Explore.java similarity index 63% rename from action/Explore.java rename to src/action/Explore.java index 16e26d3..6af87d1 100644 --- a/action/Explore.java +++ b/src/action/Explore.java @@ -1,7 +1,6 @@ package action; import info.FairyBattleInfo; -import info.Floor; import java.util.ArrayList; @@ -16,21 +15,23 @@ import walker.ErrorData; import walker.Info; import walker.Process; +import walker.Info.EventType; import action.ActionRegistry.Action; public class Explore { public static final Action Name = Action.EXPLORE; - + private static final String URL_EXPLORE = "http://web.million-arthurs.com/connect/app/exploration/guild_explore?cyt=1"; private static byte[] response; - + public static boolean run() throws Exception { ArrayList post = new ArrayList(); post.add(new BasicNameValuePair("area_id", Process.info.front.areaId)); post.add(new BasicNameValuePair("auto_build", "1")); post.add(new BasicNameValuePair("floor_id", Process.info.front.floorId)); try { - response = Process.network.ConnectToServer(URL_EXPLORE, post, false); + response = Process.network + .ConnectToServer(URL_EXPLORE, post, false); } catch (Exception ex) { if (ex.getMessage().startsWith("302")) { Process.info.events.push(Info.EventType.innerMapJump); @@ -51,68 +52,100 @@ public static boolean run() throws Exception { ErrorData.bytes = response; throw ex; } - + XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); - + try { String code = xpath.evaluate("/response/header/error/code", doc); if (!code.equals("0")) { if (code.equals("8000")) { Process.info.events.push(Info.EventType.cardFull); } + + // 限时秘境消失 + if (xpath.evaluate("/response/header/error/code", doc) + .endsWith("10000")) { + Process.info.events.push(EventType.innerMapJump); + } + ErrorData.currentErrorType = ErrorData.ErrorType.ExploreResponse; ErrorData.currentDataType = ErrorData.DataType.text; - ErrorData.text = xpath.evaluate("/response/header/error/message", doc); + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); return false; } - + Process.info.username = xpath.evaluate("//your_data/name", doc); - Process.info.lv = Integer.parseInt(xpath.evaluate("//town_level", doc)); - Process.info.ap = Integer.parseInt(xpath.evaluate("//ap/current", doc)); - Process.info.apMax = Integer.parseInt(xpath.evaluate("//ap/max", doc)); - Process.info.bc = Integer.parseInt(xpath.evaluate("//bc/current", doc)); - Process.info.bcMax = Integer.parseInt(xpath.evaluate("//bc/max", doc)); + Process.info.lv = Integer.parseInt(xpath.evaluate("//town_level", + doc)); + Process.info.ap = Integer.parseInt(xpath.evaluate("//ap/current", + doc)); + Process.info.apMax = Integer.parseInt(xpath.evaluate("//ap/max", + doc)); + Process.info.bc = Integer.parseInt(xpath.evaluate("//bc/current", + doc)); + Process.info.bcMax = Integer.parseInt(xpath.evaluate("//bc/max", + doc)); Process.info.guildId = xpath.evaluate("//your_data/party_id", doc); - Process.info.money = Long.parseLong(xpath.evaluate("//your_data/gold", doc)); - + Process.info.money = Long.parseLong(xpath.evaluate( + "//your_data/gold", doc)); + Process.info.SetTimeoutByAction(Name); - + // TODO: 添加升级事件 - Process.info.exp = Integer.parseInt(xpath.evaluate("//explore/next_exp", doc)); - - Process.info.ExploreProgress = xpath.evaluate("//explore/progress", doc); + Process.info.exp = Integer.parseInt(xpath.evaluate( + "//explore/next_exp", doc)); + + Process.info.ExploreProgress = xpath.evaluate("//explore/progress", + doc); Process.info.ExploreGold = xpath.evaluate("//explore/gold", doc); Process.info.ExploreExp = xpath.evaluate("//explore/get_exp", doc); - - int evt = Integer.parseInt(xpath.evaluate("//explore/event_type", doc)); + + int evt = Integer.parseInt(xpath.evaluate("//explore/event_type", + doc)); switch (evt) { case 22: // fairy battle Process.info.fairy = new FairyBattleInfo(); - Process.info.fairy.Type = FairyBattleInfo.PRIVATE | FairyBattleInfo.SELF; - Process.info.fairy.FairyName = xpath.evaluate("//ex_fairy/fairy/name", doc); - Process.info.fairy.FairyLevel = xpath.evaluate("//ex_fairy/fairy/lv", doc); - Process.info.fairy.SerialId = xpath.evaluate("//ex_fairy/fairy/serial_id", doc); - Process.info.fairy.UserId = xpath.evaluate("//ex_fairy/fairy/discoverer_id", doc); - Process.info.fairy.fairyCurrHp = Integer.parseInt(xpath.evaluate("//ex_fairy/fairy/hp",doc)); - Process.info.fairy.fairyMaxHp = Integer.parseInt(xpath.evaluate("//ex_fairy/fairy/hp_max",doc)); - + Process.info.fairy.Type = FairyBattleInfo.PRIVATE + | FairyBattleInfo.SELF; + Process.info.fairy.FairyName = xpath.evaluate( + "//ex_fairy/fairy/name", doc); + Process.info.fairy.FairyLevel = xpath.evaluate( + "//ex_fairy/fairy/lv", doc); + Process.info.fairy.SerialId = xpath.evaluate( + "//ex_fairy/fairy/serial_id", doc); + Process.info.fairy.UserId = xpath.evaluate( + "//ex_fairy/fairy/discoverer_id", doc); + Process.info.fairy.fairyCurrHp = Integer.parseInt(xpath + .evaluate("//ex_fairy/fairy/hp", doc)); + Process.info.fairy.fairyMaxHp = Integer.parseInt(xpath + .evaluate("//ex_fairy/fairy/hp_max", doc)); + Process.info.fairy.No = Info.PrivateFairyBattleNormal.No; + Process.info.events.push(Info.EventType.privateFairyAppear); Process.info.events.push(Info.EventType.recvPFBGood); Process.info.ExploreResult = "Fairy Appear"; break; case 5: // floor or area clear - if ((boolean)xpath.evaluate("count(//next_floor)>0", doc, XPathConstants.BOOLEAN)) { + if ((boolean) xpath.evaluate("count(//next_floor)>0", doc, + XPathConstants.BOOLEAN)) { // floor clear - Floor f = new Floor(); - f.areaId = xpath.evaluate("//next_floor/area_id", doc); - f.floorId = xpath.evaluate("//next_floor/floor_info/id", doc); - f.cost = Integer.parseInt(xpath.evaluate("//next_floor/floor_info/cost", doc)); - Process.info.front = f; - Process.info.floor.put(f.cost, f); + // Floor f = new Floor(); + // f.areaId = xpath.evaluate("//next_floor/area_id", doc); + // f.floorId = xpath.evaluate("//next_floor/floor_info/id", + // doc); + // f.cost = + // Integer.parseInt(xpath.evaluate("//next_floor/floor_info/cost", + // doc)); + // Process.info.front = f; + // Process.info.floor.put(f.cost, f); Process.info.ExploreResult = "Floor Clear"; + if (!(Info.MinAPOnly || Process.info.AllClear)) { + Process.info.events.push(Info.EventType.needFloorInfo); + } } else { Process.info.events.push(Info.EventType.areaComplete); Process.info.ExploreResult = "Area Clear"; @@ -120,17 +153,21 @@ public static boolean run() throws Exception { break; case 12: // AP - Process.info.ExploreResult = String.format("AP recover(%d)", - Integer.parseInt(xpath.evaluate("//explore/recover", doc))); + Process.info.ExploreResult = String.format("AP recover(%d)", + Integer.parseInt(xpath.evaluate("//explore/recover", + doc))); break; case 13: // BC - Process.info.ExploreResult = String.format("BC recover(%d)", - Integer.parseInt(xpath.evaluate("//explore/recover", doc))); + Process.info.ExploreResult = String.format("BC recover(%d)", + Integer.parseInt(xpath.evaluate("//explore/recover", + doc))); break; case 19: - int delta = Integer.parseInt(xpath.evaluate("//special_item/after_count", doc)) - - Integer.parseInt(xpath.evaluate("//special_item/before_count", doc)); + int delta = Integer.parseInt(xpath.evaluate( + "//special_item/after_count", doc)) + - Integer.parseInt(xpath.evaluate( + "//special_item/before_count", doc)); Process.info.ExploreResult = String.format("Gather(%d)", delta); break; case 2: @@ -143,9 +180,10 @@ public static boolean run() throws Exception { Process.info.ExploreResult = String.format("Code: %d", evt); break; } - + } catch (Exception ex) { - if (ErrorData.currentErrorType != ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType != ErrorData.ErrorType.none) + throw ex; ErrorData.currentDataType = ErrorData.DataType.bytes; ErrorData.currentErrorType = ErrorData.ErrorType.ExploreDataParseError; ErrorData.bytes = response; @@ -153,5 +191,5 @@ public static boolean run() throws Exception { } return true; } - + } diff --git a/src/action/GetFairyList.java b/src/action/GetFairyList.java new file mode 100644 index 0000000..de01978 --- /dev/null +++ b/src/action/GetFairyList.java @@ -0,0 +1,290 @@ +package action; + +import info.FairyBattleInfo; +import info.FairySelectUser; + +import java.util.ArrayList; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; + +import org.apache.http.NameValuePair; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import walker.ErrorData; +import walker.Go; +import walker.Info; +import walker.Process; +import action.ActionRegistry.Action; + +public class GetFairyList { + public static final Action Name = Action.GET_FAIRY_LIST; + + private static final String URL_FAIRY_LIST = "http://web.million-arthurs.com/connect/app/private_fairy/private_fairy_select?cyt=1"; + + private static byte[] response; + + public static boolean run() throws Exception { + try { + response = Process.network.ConnectToServer(URL_FAIRY_LIST, + new ArrayList(), false); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; + ErrorData.text = ex.getMessage(); + throw ex; + } + + Document doc; + try { + doc = Process.ParseXMLBytes(response); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.bytes; + ErrorData.currentErrorType = ErrorData.ErrorType.FairyListDataError; + ErrorData.bytes = response; + throw ex; + } + + try { + return parse(doc); + } catch (Exception ex) { + throw ex; + } + + } + + private static boolean parse(Document doc) throws Exception { + + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + + try { + if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { + ErrorData.currentErrorType = ErrorData.ErrorType.FairyListResponse; + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); + return false; + } + + if (!xpath.evaluate("//remaining_rewards", doc).equals("0")) { + if (Info.receiveBattlePresent) + Process.info.events.push(Info.EventType.fairyReward); + } + + // 获取放妖的用户 + NodeList fairyuser = (NodeList) xpath.evaluate( + "//fairy_select/user", doc, XPathConstants.NODESET); + for (int i = 0; i < fairyuser.getLength(); i++) { + Node f = fairyuser.item(i).getFirstChild(); + FairySelectUser fsu = new FairySelectUser(); + do { + if (f.getNodeName().equals("id")) { + fsu.userID = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("name")) { + fsu.userName = f.getFirstChild().getNodeValue(); + } + f = f.getNextSibling(); + } while (f != null); + if (!Process.info.FairySelectUserList.containsKey(fsu.userID)) { + Process.info.FairySelectUserList.put(fsu.userID, fsu); + } + } + + NodeList fairy = (NodeList) xpath.evaluate( + "//fairy_select/fairy_event[put_down=1]/fairy", doc, + XPathConstants.NODESET); + Process.info.OwnFairyKilled = true; + ArrayList fbis = new ArrayList(); + for (int i = 0; i < fairy.getLength(); i++) { + Node f = fairy.item(i).getFirstChild(); + FairyBattleInfo fbi = new FairyBattleInfo(); + boolean attack_flag = false; + do { + if (f.getNodeName().equals("serial_id")) { + fbi.SerialId = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("discoverer_id")) { + fbi.UserId = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("lv")) { + fbi.FairyLevel = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("name")) { + fbi.FairyName = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("rare_flg")) { + if (f.getFirstChild().getNodeValue().equals("1")) { + if (fbi.UserId == Process.info.userId) { + fbi.Type = FairyBattleInfo.PRIVATE + | FairyBattleInfo.RARE + | FairyBattleInfo.SELF; + } else { + fbi.Type = FairyBattleInfo.PRIVATE + | FairyBattleInfo.RARE; + } + } else { + if (fbi.UserId == Process.info.userId) { + fbi.Type = FairyBattleInfo.PRIVATE + | FairyBattleInfo.SELF; + } else { + fbi.Type = FairyBattleInfo.PRIVATE; + } + } + } else if (f.getNodeName().equals("hp")) { + fbi.fairyCurrHp = Integer.parseInt(f.getFirstChild() + .getNodeValue()); + } else if (f.getNodeName().equals("hp_max")) { + fbi.fairyMaxHp = Integer.parseInt(f.getFirstChild() + .getNodeValue()); + } + f = f.getNextSibling(); + } while (f != null); + + if (Info.AllowAttackSameFairy) { + fbis.add(fbi); + } else { + for (FairyBattleInfo bi : Process.info.LatestFairyList) { + if (bi.equals(fbi)) { + // 已经舔过 + attack_flag = true; + break; + } + } + if (!attack_flag) + fbis.add(fbi); + } + + if (Process.info.userId.equals(fbi.UserId)) { + Process.info.OwnFairyKilled = false; + } + + // 卡组 + if (fbis.size() > 0) { + switch (fbis.get(0).Type) { + case FairyBattleInfo.PRIVATE | FairyBattleInfo.SELF + | FairyBattleInfo.RARE: + if (Process.info.bc > Info.PrivateFairyBattleRare.BC) { + fbis.get(0).No = Info.PrivateFairyBattleRare.No; + break; + } + case FairyBattleInfo.PRIVATE | FairyBattleInfo.SELF: + fbis.get(0).No = Info.PrivateFairyBattleNormal.No; + break; + case FairyBattleInfo.PRIVATE | FairyBattleInfo.RARE: + if (Process.info.bc > Info.FriendFairyBattleRare.BC) { + fbis.get(0).No = Info.FriendFairyBattleRare.No; + break; + } + case FairyBattleInfo.PRIVATE: + fbis.get(0).No = Info.FriendFairyBattleNormal.No; + break; + default: + break; + } + } + }// end for + + if (fbis.size() == 0) { + // 活动妖,第一次0BC + NodeList fairyEvent = (NodeList) xpath.evaluate( + "//fairy_select/fairy_event[put_down=4]/fairy", doc, + XPathConstants.NODESET); + + for (int i = 0; i < fairyEvent.getLength(); i++) { + Node f = fairyEvent.item(i).getFirstChild(); + FairyBattleInfo fbi = new FairyBattleInfo(); + boolean attack_flag = false; + do { + if (f.getNodeName().equals("serial_id")) { + fbi.SerialId = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("discoverer_id")) { + fbi.UserId = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("lv")) { + fbi.FairyLevel = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("name")) { + fbi.FairyName = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("rare_flg")) { + if (f.getFirstChild().getNodeValue().equals("1")) { + if (fbi.UserId == Process.info.userId) { + fbi.Type = FairyBattleInfo.PRIVATE + | FairyBattleInfo.RARE + | FairyBattleInfo.SELF; + } else { + fbi.Type = FairyBattleInfo.PRIVATE + | FairyBattleInfo.RARE; + } + } else { + fbi.Type = FairyBattleInfo.PRIVATE; + } + } else if (f.getNodeName().equals("hp")) { + fbi.fairyCurrHp = Integer.parseInt(f + .getFirstChild().getNodeValue()); + } else if (f.getNodeName().equals("hp_max")) { + fbi.fairyMaxHp = Integer.parseInt(f.getFirstChild() + .getNodeValue()); + } + f = f.getNextSibling(); + } while (f != null); + + // 使用外敌卡组 + fbi.No = Info.PublicFairyBattle.No; + + fbis.add(fbi); + + if (Process.info.userId.equals(fbi.UserId)) { + Process.info.OwnFairyKilled = false; + } + }// end for + } + + if (fbis.size() > 1) + Process.info.events.push(Info.EventType.fairyAppear); // 以便再次寻找 + if (fbis.size() > 0) { + if (!Process.info.events.contains("gotoFloor")) + Process.info.events.push(Info.EventType.gotoFloor); + Process.info.events.push(Info.EventType.recvPFBGood); + Process.info.events.push(Info.EventType.fairyCanBattle); + Process.info.fairy = new FairyBattleInfo(fbis.get(0)); + } + + NodeList fairy1 = (NodeList) xpath.evaluate( + "//fairy_select/fairy_event[put_down=5]/fairy", doc, + XPathConstants.NODESET); + + int aa = fairy1.getLength(); + + Go.log("找到" + aa + "个可赞的PFB..."); + for (int i = 0; i < fairy1.getLength(); i++) { + Node f = fairy1.item(i).getFirstChild(); + String serial_Id = ""; + String user_Id = ""; + do { + if (f.getNodeName().equals("serial_id")) { + serial_Id = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("discoverer_id")) { + user_Id = f.getFirstChild().getNodeValue(); + } + f = f.getNextSibling(); + } while (f != null); + Process.info.PFBGoodList.push(new info.PFBGood(serial_Id, + user_Id)); + } + if (!Process.info.PFBGoodList.isEmpty()) { + Process.info.events.push(Info.EventType.PFBGood); + } + + Process.info.SetTimeoutByAction(Name); + + } catch (Exception ex) { + if (ErrorData.currentErrorType != ErrorData.ErrorType.none) + throw ex; + ErrorData.currentDataType = ErrorData.DataType.bytes; + ErrorData.currentErrorType = ErrorData.ErrorType.FairyListDataParseError; + ErrorData.bytes = response; + throw ex; + } + + return true; + + } +} diff --git a/action/GetFairyReward.java b/src/action/GetFairyReward.java similarity index 88% rename from action/GetFairyReward.java rename to src/action/GetFairyReward.java index 9c28ab8..75a4451 100644 --- a/action/GetFairyReward.java +++ b/src/action/GetFairyReward.java @@ -13,6 +13,8 @@ public class GetFairyReward { public static final Action Name = Action.GET_FAIRY_REWARD; private static final String URL_GET_FAIRY_REWARD = "http://web.million-arthurs.com/connect/app/private_fairy/private_fairy_rewards?cyt=1"; + //private static final String URL_GET_FAIRY_REWARD = "http://web.million-arthurs.com/connect/app/menu/rewardbox?cyt=1"; + //private static final String URL_GET_FAIRY_REWARD = "http://web.million-arthurs.com/connect/app/menu/get_rewards?cyt=1"; private static byte[] response; public static boolean run() throws Exception { diff --git a/action/GetFloorInfo.java b/src/action/GetFloorInfo.java similarity index 51% rename from action/GetFloorInfo.java rename to src/action/GetFloorInfo.java index 0a00ba6..5569ace 100644 --- a/action/GetFloorInfo.java +++ b/src/action/GetFloorInfo.java @@ -4,7 +4,6 @@ import info.Floor; import java.util.ArrayList; -//import java.util.Hashtable; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; @@ -16,32 +15,31 @@ import org.w3c.dom.NodeList; import walker.ErrorData; +import walker.Info; import walker.Process; import action.ActionRegistry.Action; public class GetFloorInfo { public static final Action Name = Action.GET_FLOOR_INFO; - + private static final String URL_AREA = "http://web.million-arthurs.com/connect/app/exploration/area?cyt=1"; private static final String URL_FLOOR = "http://web.million-arthurs.com/connect/app/exploration/floor?cyt=1"; - - + private static byte[] response; - + public static boolean run() throws Exception { response = null; Document doc; try { - response = Process.network.ConnectToServer(URL_AREA, new ArrayList(), false); + response = Process.network.ConnectToServer(URL_AREA, + new ArrayList(), false); } catch (Exception ex) { - //if (ex.getMessage().equals("302")) - // 上面的是为了截获里图跳转 ErrorData.currentDataType = ErrorData.DataType.text; ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; ErrorData.text = ex.getMessage(); throw ex; } - + try { doc = Process.ParseXMLBytes(response); } catch (Exception ex) { @@ -50,62 +48,117 @@ public static boolean run() throws Exception { ErrorData.bytes = response; throw ex; } - + try { XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { ErrorData.currentErrorType = ErrorData.ErrorType.AreaResponse; ErrorData.currentDataType = ErrorData.DataType.text; - ErrorData.text = xpath.evaluate("/response/header/error/message", doc); + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); return false; } - - int areaCount = ((NodeList)xpath.evaluate("//area_info_list/area_info", doc, XPathConstants.NODESET)).getLength(); + + int areaCount = ((NodeList) xpath.evaluate( + "//area_info_list/area_info", doc, XPathConstants.NODESET)) + .getLength(); if (areaCount > 0) { - //Process.info.area = new Hashtable(); Process.info.area.clear(); Process.info.floor.clear(); } - for (int i = 1; i <= areaCount; i++){ + + for (int i = 1; i <= areaCount; i++) { Area a = new Area(); - String p = String.format("//area_info_list/area_info[%d]/",i); - a.areaId = Integer.parseInt(xpath.evaluate(p+"id", doc)); - a.areaName = xpath.evaluate(p+"name", doc); - a.exploreProgress = Integer.parseInt(xpath.evaluate(p+"prog_area", doc)); - if (a.areaId > 100000) Process.info.area.put(a.areaId, a); + String p = String.format("//area_info_list/area_info[%d]/", i); + a.areaId = Integer.parseInt(xpath.evaluate(p + "id", doc)); + a.areaName = xpath.evaluate(p + "name", doc); + a.exploreProgress = Integer.parseInt(xpath.evaluate(p + + "prog_area", doc)); + a.areaType = (a.areaId >= Info.InnerMapNo) ? 1 : 0; + if (a.areaType == 1) { + if (Info.InnerInstance) + Process.info.area.put(a.areaId, a); + } else if (a.areaId > 100000) + Process.info.area.put(a.areaId, a); + if (Info.SpecilInstance && a.areaId >= 50000 + && a.areaId <= 50010) + Process.info.area.put(a.areaId, a); } + Process.info.AllClear = true; Process.info.front = null; - for (int i : Process.info.area.keySet()) { - getFloor(Process.info.area.get(i)); - } // end of area iterator - if (Process.info.front == null) Process.info.front = Process.info.floor.get(1); + + // 日常图逻辑 + boolean flag = false; + for (int i = 50000; i <= 50010; i++) { + if (Process.info.area.containsKey(i) + && Process.info.area.get(i).exploreProgress < 100) { + getFloor(Process.info.area.get(i)); + flag = true; + break; + } + } + + if (flag == false) { + for (int i : Process.info.area.keySet()) { + getFloor(Process.info.area.get(i)); + } // end of area iterator + } + + int floor = Process.info.floor.firstKey(); + if (Info.MinAPOnly || Process.info.AllClear) { + if (Info.InnerInstance) { + for (int i : Process.info.floor.keySet()) { + if (Process.info.floor.get(i).innerFlag) { + Process.info.front = Process.info.floor.get(i); + break; + } + } + } else { + for (int i : Process.info.floor.keySet()) { + if (!Process.info.floor.get(i).innerFlag) { + Process.info.front = Process.info.floor.get(i); + break; + } + } + } + } else { + for (int i : Process.info.floor.keySet()) { + if (!Info.InnerInstance) { + if (Process.info.floor.get(i).innerFlag) { + Process.info.floor.remove(i); + } + } + } + floor = Process.info.floor.lastKey(); + } + + if (Process.info.front == null) + Process.info.front = Process.info.floor.get(floor); Process.info.SetTimeoutByAction(Name); - } catch (Exception ex) { if (ErrorData.currentErrorType == ErrorData.ErrorType.none) { throw ex; } } - + return true; } - + public static void getFloor(Area a) throws Exception { ArrayList post = new ArrayList(); post.add(new BasicNameValuePair("area_id", String.valueOf(a.areaId))); try { response = Process.network.ConnectToServer(URL_FLOOR, post, false); } catch (Exception ex) { - //if (ex.getMessage().equals("302")) - // 上面的是为了截获里图跳转 ErrorData.currentDataType = ErrorData.DataType.text; ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; ErrorData.text = ex.getLocalizedMessage(); throw ex; } Document doc; + try { doc = Process.ParseXMLBytes(response); } catch (Exception ex) { @@ -114,35 +167,45 @@ public static void getFloor(Area a) throws Exception { ErrorData.bytes = response; throw ex; } - + XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); - - int floorCount = ((NodeList)xpath.evaluate("//floor_info_list/floor_info", doc, XPathConstants.NODESET)).getLength(); + + int floorCount = ((NodeList) xpath.evaluate( + "//floor_info_list/floor_info", doc, XPathConstants.NODESET)) + .getLength(); String aid = xpath.evaluate("//exploration_floor/area_id", doc); - + for (int j = floorCount; j > 0; j--) { Floor f = new Floor(); String p = String.format("//floor_info_list/floor_info[%d]/", j); f.areaId = aid; - f.floorId = xpath.evaluate(p+"id", doc); - f.cost = Integer.parseInt(xpath.evaluate(p+"cost", doc)); - f.progress = Integer.parseInt(xpath.evaluate(p+"progress", doc)); - f.type = xpath.evaluate(p+"type", doc); - if (Integer.parseInt(f.areaId) < 100000 && f.cost < 1) continue; //跳过秘境守护者 + f.floorId = xpath.evaluate(p + "id", doc); + f.cost = Integer.parseInt(xpath.evaluate(p + "cost", doc)); + f.progress = Integer.parseInt(xpath.evaluate(p + "progress", doc)); + f.type = xpath.evaluate(p + "type", doc); + f.innerFlag = (a.areaType == 1) ? true : false; + + int areaId = Integer.parseInt(f.areaId); + if (areaId < 100000 && f.cost < 1 + && (areaId < 50000 || areaId > 50010)) { + continue; // 跳过秘境守护者 + } + if (Process.info.floor.containsKey(f.cost)) { - if(Integer.parseInt(Process.info.floor.get(f.cost).areaId) > Integer.parseInt(f.areaId)) { + if (Integer.parseInt(Process.info.floor.get(f.cost).areaId) > Integer + .parseInt(f.areaId)) { continue; } } + Process.info.floor.put(f.cost, f); - if (f.progress != 100 && a.exploreProgress != 100 && Process.info.AllClear) { + if (f.progress != 100 && a.exploreProgress != 100 + && Process.info.AllClear) { Process.info.front = f; Process.info.AllClear = false; } } } - - - + } diff --git a/src/action/GetRank.java b/src/action/GetRank.java new file mode 100644 index 0000000..09dbb61 --- /dev/null +++ b/src/action/GetRank.java @@ -0,0 +1,73 @@ +package action; + +import java.util.ArrayList; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathFactory; + +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicNameValuePair; +import org.w3c.dom.Document; + +import walker.ErrorData; +import walker.Process; + +public class GetRank { + private static final String URL_RANKING_NEXT = "http://web.million-arthurs.com/connect/app/ranking/ranking_next?cyt=1"; + private static byte[] response; + + public static int gatherrank(int iUser, int rId) throws Exception { + Document doc; + try { + ArrayList al = new ArrayList(); + al.add(new BasicNameValuePair("from", String.valueOf(iUser))); + al.add(new BasicNameValuePair("ranktype_id", String.format("%d", + rId))); + + response = Process.network.ConnectToServer(URL_RANKING_NEXT, al, + false); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; + ErrorData.text = ex.getMessage(); + throw ex; + } + + try { + doc = Process.ParseXMLBytes(response); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.bytes; + ErrorData.currentErrorType = ErrorData.ErrorType.PFB_GoodDataError; + ErrorData.bytes = response; + throw ex; + } + + try { + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { + ErrorData.currentErrorType = ErrorData.ErrorType.FairyHistoryResponse; + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); + return 0; + } + + String rank = xpath.evaluate("//user_list/user[1]/rank", doc); + if ("".equals(rank) == false) { + return Integer.parseInt(rank) - 1; + } else { + // no rank info found + return 0; + } + + } catch (Exception ex) { + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) { + throw ex; + } + } + + return 0; + } + +} diff --git a/src/action/GetRewardBox.java b/src/action/GetRewardBox.java new file mode 100644 index 0000000..e58c7a1 --- /dev/null +++ b/src/action/GetRewardBox.java @@ -0,0 +1,132 @@ +package action; + +import info.Box; +import java.util.ArrayList; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicNameValuePair; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; + +import walker.ErrorData; +import walker.Go; +import walker.Process; + +public class GetRewardBox { + private static final String URL_LIST_REWARD_BOX = "http://web.million-arthurs.com/connect/app/menu/rewardbox?cyt=1"; + private static final String URL_GET_REWARD_BOX = "http://web.million-arthurs.com/connect/app/menu/get_rewards?cyt=1"; + + private static byte[] response; + + public static void list() throws Exception { + Document doc; + try { + response = Process.network.ConnectToServer(URL_LIST_REWARD_BOX, + new ArrayList(), false); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; + ErrorData.text = ex.getMessage(); + throw ex; + } + + try { + doc = Process.ParseXMLBytes(response); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.bytes; + ErrorData.currentErrorType = ErrorData.ErrorType.GetRewardBoxDataError; + ErrorData.bytes = response; + throw ex; + } + parse(doc); + } + + public static void parse(Document doc) throws NumberFormatException, + XPathExpressionException { + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + + int boxCount = ((NodeList) xpath.evaluate("//rewardbox_list/rewardbox", + doc, XPathConstants.NODESET)).getLength(); + Process.info.boxList = new ArrayList(); + for (int i = 1; i < boxCount + 1; i++) { + Box b = new Box(); + String p = String.format("//rewardbox_list/rewardbox[%d]", i); + + b.boxId = xpath.evaluate(p + "/id", doc); + b.boxType = Integer.parseInt(xpath.evaluate(p + "/type", doc)); + b.exist = true; + Process.info.boxList.add(b); + } + } + + public static void get() throws Exception { + Document doc; + int count = 0; + String toGet = ""; + for (Box b : Process.info.boxList) { + if (!b.exist) + continue; + if (toGet.isEmpty()) { + toGet = b.boxId; + } else { + toGet += "," + b.boxId; + } + count++; + b.exist = false; + if (count >= 20) + break; + } + + Process.info.toGet = toGet; + + if (!toGet.isEmpty()) { + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + ArrayList post = new ArrayList(); + post.add(new BasicNameValuePair("notice_id", Process.info.toGet)); + try { + response = Process.network.ConnectToServer(URL_GET_REWARD_BOX, + post, false); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; + ErrorData.text = ex.getLocalizedMessage(); + throw ex; + } + + try { + doc = Process.ParseXMLBytes(response); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.bytes; + ErrorData.currentErrorType = ErrorData.ErrorType.GetRewardBoxDataError; + ErrorData.bytes = response; + throw ex; + } + + try { + if (!xpath.evaluate("/response/header/error/code", doc).equals( + "0")) { + ErrorData.currentErrorType = ErrorData.ErrorType.GetRewardBoxReponse; + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); + Go.log(ErrorData.text); + } + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.bytes; + ErrorData.currentErrorType = ErrorData.ErrorType.GetRewardBoxDataError; + ErrorData.bytes = response; + throw ex; + } + + ParseCardList.parse(doc); + } + } + +} \ No newline at end of file diff --git a/action/GotoFloor.java b/src/action/GotoFloor.java similarity index 75% rename from action/GotoFloor.java rename to src/action/GotoFloor.java index 43cdccf..147ab15 100644 --- a/action/GotoFloor.java +++ b/src/action/GotoFloor.java @@ -11,31 +11,33 @@ import walker.ErrorData; import walker.Process; +import walker.Info.EventType; import action.ActionRegistry.Action; public class GotoFloor { public static final Action Name = Action.GOTO_FLOOR; - + private static final String URL_GET_FLOOR = "http://web.million-arthurs.com/connect/app/exploration/get_floor?cyt=1"; - + private static byte[] response; - + public static boolean run() throws Exception { ArrayList post = new ArrayList(); post.add(new BasicNameValuePair("area_id", Process.info.front.areaId)); - post.add(new BasicNameValuePair("check","1")); - post.add(new BasicNameValuePair("floor_id",Process.info.front.floorId)); + post.add(new BasicNameValuePair("check", "1")); + post.add(new BasicNameValuePair("floor_id", Process.info.front.floorId)); try { - response = Process.network.ConnectToServer(URL_GET_FLOOR, post, false); + response = Process.network.ConnectToServer(URL_GET_FLOOR, post, + false); } catch (Exception ex) { - //if (ex.getMessage().equals("302")) + // if (ex.getMessage().equals("302")) // 上面的是为了截获里图跳转 ErrorData.currentDataType = ErrorData.DataType.text; ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; ErrorData.text = ex.getMessage(); throw ex; } - + Document doc; try { doc = Process.ParseXMLBytes(response); @@ -45,43 +47,57 @@ public static boolean run() throws Exception { ErrorData.bytes = response; throw ex; } - + XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); - - + try { if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { + // 限时秘境消失 + if (xpath.evaluate("/response/header/error/code", doc) + .endsWith("10000")) { + Process.info.events.push(EventType.innerMapJump); + } + ErrorData.currentErrorType = ErrorData.ErrorType.GotoFloorResponse; ErrorData.currentDataType = ErrorData.DataType.text; - ErrorData.text = xpath.evaluate("/response/header/error/message", doc); + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); return false; } Process.info.username = xpath.evaluate("//your_data/name", doc); - Process.info.lv = Integer.parseInt(xpath.evaluate("//town_level", doc)); - Process.info.ap = Integer.parseInt(xpath.evaluate("//ap/current", doc)); - Process.info.apMax = Integer.parseInt(xpath.evaluate("//ap/max", doc)); - Process.info.bc = Integer.parseInt(xpath.evaluate("//bc/current", doc)); - Process.info.bcMax = Integer.parseInt(xpath.evaluate("//bc/max", doc)); + Process.info.lv = Integer.parseInt(xpath.evaluate("//town_level", + doc)); + Process.info.ap = Integer.parseInt(xpath.evaluate("//ap/current", + doc)); + Process.info.apMax = Integer.parseInt(xpath.evaluate("//ap/max", + doc)); + Process.info.bc = Integer.parseInt(xpath.evaluate("//bc/current", + doc)); + Process.info.bcMax = Integer.parseInt(xpath.evaluate("//bc/max", + doc)); Process.info.guildId = xpath.evaluate("//your_data/party_id", doc); - + Process.info.SetTimeoutByAction(Name); - - Process.info.exp = Integer.parseInt(xpath.evaluate("//get_floor/next_exp", doc)); - String spec = xpath.evaluate("//get_floor/special_item/before_count", doc); + + Process.info.exp = Integer.parseInt(xpath.evaluate( + "//get_floor/next_exp", doc)); + String spec = xpath.evaluate( + "//get_floor/special_item/before_count", doc); if (spec.length() != 0) { Process.info.gather = Integer.parseInt(spec); } else { Process.info.gather = -1; } } catch (Exception ex) { - if (ErrorData.currentErrorType != ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType != ErrorData.ErrorType.none) + throw ex; ErrorData.currentDataType = ErrorData.DataType.bytes; ErrorData.currentErrorType = ErrorData.ErrorType.GotoFloorDataParseError; ErrorData.bytes = response; throw ex; } - + return true; } } diff --git a/action/GuildBattle.java b/src/action/GuildBattle.java similarity index 88% rename from action/GuildBattle.java rename to src/action/GuildBattle.java index ec5b407..62170a3 100644 --- a/action/GuildBattle.java +++ b/src/action/GuildBattle.java @@ -72,6 +72,10 @@ public static boolean run() throws Exception { } Process.info.week = xpath.evaluate("//week_total_contribution", doc); + Process.info.exp = Integer.parseInt(xpath.evaluate("//own_fairy_battle_result/user_state_new/exp_next", doc)); + Process.info.gfairy.battle_contribution = xpath.evaluate("//battle_contribution", doc); + Process.info.gfairy.hp_contribution = xpath.evaluate("//hp_contribution", doc); + Process.info.gfairy.contribution = xpath.evaluate("//contribution", doc); Process.info.SetTimeoutByAction(Name); diff --git a/action/GuildDefeat.java b/src/action/GuildDefeat.java similarity index 100% rename from action/GuildDefeat.java rename to src/action/GuildDefeat.java diff --git a/action/GuildTop.java b/src/action/GuildTop.java similarity index 85% rename from action/GuildTop.java rename to src/action/GuildTop.java index d592129..feaa752 100644 --- a/action/GuildTop.java +++ b/src/action/GuildTop.java @@ -8,6 +8,7 @@ import org.apache.http.NameValuePair; import org.w3c.dom.Document; +import org.w3c.dom.NodeList; import walker.ErrorData; import walker.Info; @@ -74,6 +75,12 @@ public static boolean run() throws Exception { Process.info.gfairy.FairyLevel = xpath.evaluate("//fairy/lv", doc); Process.info.gfairy.fairyCurrHp = Integer.parseInt(xpath.evaluate("//fairy/hp", doc)); Process.info.gfairy.fairyMaxHp = Integer.parseInt(xpath.evaluate("//fairy/hp_max", doc)); + Process.info.gfairy.Spp = xpath.evaluate("//spp_skill_effect", doc);//使用BC3%回復 + int i = ((NodeList)xpath.evaluate("//guild_log", doc, XPathConstants.NODESET)).getLength(); + String p = String.format("//guild_log[%d]", i); + Process.info.gfairy.UserId = xpath.evaluate(p+"/user_name", doc); + Process.info.gfairy.attack_compensation = xpath.evaluate("//attack_compensation", doc); + //Go.log(String.format("最后攻击的是%s",Process.info.gfairy.UserId)); Process.info.events.push(Info.EventType.guildBattle); diff --git a/action/Login.java b/src/action/Login.java similarity index 70% rename from action/Login.java rename to src/action/Login.java index d9d01e1..32b764a 100644 --- a/action/Login.java +++ b/src/action/Login.java @@ -1,5 +1,6 @@ package action; +import info.Box; import java.util.ArrayList; @@ -11,8 +12,10 @@ import org.w3c.dom.Document; import walker.ErrorData; +import walker.Go; import walker.Info; import walker.Process; +import walker.Think; public class Login { public static final ActionRegistry.Action Name = ActionRegistry.Action.LOGIN; @@ -22,22 +25,24 @@ public class Login { // error type public static final String ERR_CHECK_INSPECTION = "Login/check_inspection"; public static final String ERR_LOGIN = "Login/login"; - + private static byte[] result; - + public static boolean run() throws Exception { try { return run(true); } catch (Exception ex) { throw ex; } + } - + public static boolean run(boolean jump) throws Exception { Document doc; if (!jump) { try { - result = Process.network.ConnectToServer(URL_CHECK_INSPECTION, new ArrayList(), true); + result = Process.network.ConnectToServer(URL_CHECK_INSPECTION, + new ArrayList(), true); } catch (Exception ex) { ErrorData.currentDataType = ErrorData.DataType.text; ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; @@ -46,10 +51,10 @@ public static boolean run(boolean jump) throws Exception { } } ArrayList al = new ArrayList(); - al.add(new BasicNameValuePair("login_id",Info.LoginId)); - al.add(new BasicNameValuePair("password",Info.LoginPw)); + al.add(new BasicNameValuePair("login_id", Info.LoginId)); + al.add(new BasicNameValuePair("password", Info.LoginPw)); try { - result = Process.network.ConnectToServer(URL_LOGIN, al,true); + result = Process.network.ConnectToServer(URL_LOGIN, al, true); } catch (Exception ex) { ErrorData.currentDataType = ErrorData.DataType.text; ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; @@ -71,7 +76,7 @@ public static boolean run(boolean jump) throws Exception { throw ex; } } - + private static boolean parse(Document doc) throws Exception { try { XPathFactory factory = XPathFactory.newInstance(); @@ -79,28 +84,31 @@ private static boolean parse(Document doc) throws Exception { if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { ErrorData.currentErrorType = ErrorData.ErrorType.LoginResponse; ErrorData.currentDataType = ErrorData.DataType.text; - ErrorData.text = xpath.evaluate("/response/header/error/message", doc); + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); return false; } - + if (GuildDefeat.judge(doc)) { return false; } - + if (!xpath.evaluate("//fairy_appearance", doc).equals("0")) { Process.info.events.push(Info.EventType.fairyAppear); } - + Process.info.userId = xpath.evaluate("//login/user_id", doc); ParseUserDataInfo.parse(doc); ParseCardList.parse(doc); - + Process.info.SetTimeoutByAction(Name); - - Process.info.cardMax = Integer.parseInt(xpath.evaluate("//your_data/max_card_num",doc)); - + + Process.info.cardMax = Integer.parseInt(xpath.evaluate( + "//your_data/max_card_num", doc)); + } catch (Exception ex) { - if (ErrorData.currentErrorType != ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType != ErrorData.ErrorType.none) + throw ex; ErrorData.currentDataType = ErrorData.DataType.bytes; ErrorData.currentErrorType = ErrorData.ErrorType.LoginDataParseError; ErrorData.bytes = result; @@ -108,5 +116,34 @@ private static boolean parse(Document doc) throws Exception { } return true; } - -} + + public static void listRewardbox() throws Exception { + GetRewardBox.list(); + Go.log(String.format("你的报酬箱里有[%d]个物品。", Process.info.boxList.size())); + do { + for (int i = 0; i < Process.info.boxList.size(); i++) { + Box b = Process.info.boxList.get(i); + if (!b.exist) + Process.info.boxList.remove(i); + } + + if (Process.info.boxList.size() == 0) { + break; + } + + GetRewardBox.get(); + + // sell card + if (Info.autoSellCard == true && Think.cardsToSell() == true) { + SellCard.run(); + Go.log(ErrorData.text); + ErrorData.clear(); + } + + if (Process.info.cardList.size() == 300) { + break; + } + } while (true); + } + +} \ No newline at end of file diff --git a/action/LvUp.java b/src/action/LvUp.java similarity index 100% rename from action/LvUp.java rename to src/action/LvUp.java diff --git a/action/PFBGood.java b/src/action/PFBGood.java similarity index 100% rename from action/PFBGood.java rename to src/action/PFBGood.java diff --git a/action/ParseCardList.java b/src/action/ParseCardList.java similarity index 95% rename from action/ParseCardList.java rename to src/action/ParseCardList.java index 9657f6e..a722976 100644 --- a/action/ParseCardList.java +++ b/src/action/ParseCardList.java @@ -31,6 +31,7 @@ public static void parse(Document doc) throws NumberFormatException, XPathExpres c.hp = Integer.parseInt(xpath.evaluate(p+"/hp", doc)); c.atk = Integer.parseInt(xpath.evaluate(p+"/power", doc)); c.plusLimit = Integer.parseInt(xpath.evaluate(p+"/plus_limit_count", doc)); + c.price = Integer.parseInt(xpath.evaluate(p+"/sale_price", doc)); c.exist = true; Process.info.cardList.add(c); } diff --git a/action/ParseUserDataInfo.java b/src/action/ParseUserDataInfo.java similarity index 100% rename from action/ParseUserDataInfo.java rename to src/action/ParseUserDataInfo.java diff --git a/src/action/PartyRank.java b/src/action/PartyRank.java new file mode 100644 index 0000000..bb5203b --- /dev/null +++ b/src/action/PartyRank.java @@ -0,0 +1,255 @@ +package action; + +import info.PartyInfo; +import info.PlayerRank; + +import java.util.ArrayList; +import java.util.Collections; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; + +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicNameValuePair; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import walker.ErrorData; +import walker.Go; +import walker.Process; +import action.ActionRegistry.Action; + +public class PartyRank { + public static final Action Name = Action.PARTY_RANK; + + @SuppressWarnings("unused") + private static final String URL_GUIDE_MEMBER_LIST = "http://web.million-arthurs.com/connect/app/guild/guild_member_list?cyt=1"; + private static final String URL_PARTY_ONLY_MEMBER_LIST = "http://web.million-arthurs.com/connect/app/party/party_only_member_list?cyt=1"; + private static final String URL_GUILD_INFO = "http://web.million-arthurs.com/connect/app/guild/guild_info?cyt=1"; + private static final String URL_RANKING_NEXT = "http://web.million-arthurs.com/connect/app/ranking/ranking_next?cyt=1"; + private static byte[] response; + + public static boolean run() throws Exception { + Document doc; + Boolean set = false; + + try { + response = Process.network.ConnectToServer(URL_GUILD_INFO, + new ArrayList(), false); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; + ErrorData.text = ex.getMessage(); + throw ex; + } + + try { + /*doc = Process.ParseXMLBytes(response, new Object() { + public String getClassName() { + String clazzName = this.getClass().getName(); + return clazzName.substring(0, clazzName.lastIndexOf('$')); + } + }.getClassName()); */// 通过分析匿名类获得当前类名 + doc = Process.ParseXMLBytes(response); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.bytes; + ErrorData.currentErrorType = ErrorData.ErrorType.PartyRankDataParseError; + ErrorData.bytes = response; + throw ex; + } + + try { + set = parse(doc); + } catch (Exception ex) { + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) { + throw ex; + } + } + + return set; + } + + private static boolean parse(Document doc) throws Exception { + + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + + try { + if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { + ErrorData.currentErrorType = ErrorData.ErrorType.FairyHistoryResponse; + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); + return false; + } + + PartyInfo.user_rank = xpath.evaluate("//guild_info/user_rank", doc); + PartyInfo.user_hunting_point = xpath.evaluate( + "//guild_info/user_hunting_point", doc); + PartyInfo.own_guild_point = xpath.evaluate( + "//guild_info/guild_hunting_point/own_guild_point", doc); + PartyInfo.own_guild_dairy_point = xpath.evaluate( + "//guild_info/guild_hunting_point/own_guild_dairy_point", + doc); + PartyInfo.own_guild_rank = xpath.evaluate( + "//guild_info/own_guild_rank", doc); + PartyInfo.rival_guild_point = xpath.evaluate( + "//guild_info/guild_hunting_point/rival_guild_point", doc); + PartyInfo.rival_guild_dairy_point = xpath.evaluate( + "//guild_info/guild_hunting_point/rival_guild_dairy_point", + doc); + PartyInfo.rival_guild_rank = xpath.evaluate( + "//guild_info/rival_guild_rank", doc); + + run2(Process.info.guildId); + + Process.info.SetTimeoutByAction(Name); + + } catch (Exception ex) { + if (ErrorData.currentErrorType != ErrorData.ErrorType.none) + throw ex; + ErrorData.currentDataType = ErrorData.DataType.bytes; + ErrorData.currentErrorType = ErrorData.ErrorType.FairyHistoryDataParseError; + ErrorData.bytes = response; + throw ex; + } + return true; + } + + public static boolean run2(String guildId) throws Exception { + Document doc; + try { + ArrayList al = new ArrayList(); + al.add(new BasicNameValuePair("pid", guildId)); + response = Process.network.ConnectToServer( + URL_PARTY_ONLY_MEMBER_LIST, al, false); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; + ErrorData.text = ex.getMessage(); + throw ex; + } + + try { + /*doc = Process.ParseXMLBytes(response, new Object() { + public String getClassName() { + String clazzName = this.getClass().getName(); + return clazzName.substring(0, clazzName.lastIndexOf('$')); + } + }.getClassName()); */// 通过分析匿名类获得当前类名 + doc = Process.ParseXMLBytes(response); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.bytes; + ErrorData.currentErrorType = ErrorData.ErrorType.PFB_GoodDataError; + ErrorData.bytes = response; + throw ex; + } + + try { + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { + ErrorData.currentErrorType = ErrorData.ErrorType.FairyHistoryResponse; + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); + return false; + } + + NodeList fairyuser = (NodeList) xpath.evaluate( + "//party_member_list/member", doc, XPathConstants.NODESET); + int num = 0; + PartyInfo.ranklist.clear(); + for (int i = 0; i < fairyuser.getLength(); i++) { + Node f = fairyuser.item(i).getFirstChild(); + PlayerRank item = new PlayerRank(); + int iUser = 0; + do { + if (f.getNodeName().equals("id")) { + iUser = Integer.parseInt(f.getFirstChild() + .getNodeValue()); + } else if (f.getNodeName().equals("name")) { + item.name = f.getFirstChild().getNodeValue(); + } else if (f.getNodeName().equals("guild_hunting_point")) { + num += item.point = Integer.parseInt(f.getFirstChild() + .getNodeValue()); + } else if (f.getNodeName().equals("town_level")) { + item.ilv = Integer.parseInt(f.getFirstChild() + .getNodeValue()); + } else if (f.getNodeName().equals("last_login")) { + item.logintime = f.getFirstChild().getNodeValue(); + } + f = f.getNextSibling(); + } while (f != null); + item.irank = geturerrank(iUser); + PartyInfo.ranklist.add(item); + } + + String str2 = String.format("团贡 :%d / %s,日贡:%s,团排:%s\r\n", num, + PartyInfo.own_guild_point, PartyInfo.own_guild_dairy_point, + PartyInfo.own_guild_rank); + Go.log(str2); + Collections.sort(PartyInfo.ranklist); + for (PlayerRank playerrank2 : PartyInfo.ranklist) + { + Go.log(playerrank2.toString()); + } + + } catch (Exception ex) { + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) { + throw ex; + } + } + + return false; + } + + public static int geturerrank(int iUser) throws Exception { + Document doc; + try { + ArrayList al = new ArrayList(); + al.add(new BasicNameValuePair("from", String.valueOf(iUser))); + al.add(new BasicNameValuePair("ranktype_id", "4")); + response = Process.network.ConnectToServer(URL_RANKING_NEXT, al, + false); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; + ErrorData.text = ex.getMessage(); + throw ex; + } + + try { + doc = Process.ParseXMLBytes(response); + } catch (Exception ex) { + ErrorData.currentDataType = ErrorData.DataType.bytes; + ErrorData.currentErrorType = ErrorData.ErrorType.PFB_GoodDataError; + ErrorData.bytes = response; + throw ex; + } + + try { + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { + ErrorData.currentErrorType = ErrorData.ErrorType.FairyHistoryResponse; + ErrorData.currentDataType = ErrorData.DataType.text; + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); + return 0; + } + + return Integer.parseInt(xpath.evaluate("//user_list/user[1]/rank", + doc)) - 1; + + } catch (Exception ex) { + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) { + throw ex; + } + } + + return 0; + } +} diff --git a/action/PrivateFairyBattle.java b/src/action/PrivateFairyBattle.java similarity index 63% rename from action/PrivateFairyBattle.java rename to src/action/PrivateFairyBattle.java index 5f74e87..626efb5 100644 --- a/action/PrivateFairyBattle.java +++ b/src/action/PrivateFairyBattle.java @@ -19,18 +19,20 @@ public class PrivateFairyBattle { public static final Action Name = Action.PRIVATE_FAIRY_BATTLE; - + private static final String URL_PRIVATE_BATTLE = "http://web.million-arthurs.com/connect/app/private_fairy/private_fairy_battle?cyt=1"; - + private static byte[] response; - + public static boolean run() throws Exception { ArrayList post = new ArrayList(); post.add(new BasicNameValuePair("no", Process.info.fairy.No)); - post.add(new BasicNameValuePair("serial_id", Process.info.fairy.SerialId)); + post.add(new BasicNameValuePair("serial_id", + Process.info.fairy.SerialId)); post.add(new BasicNameValuePair("user_id", Process.info.fairy.UserId)); try { - response = Process.network.ConnectToServer(URL_PRIVATE_BATTLE, post, false); + response = Process.network.ConnectToServer(URL_PRIVATE_BATTLE, + post, false); } catch (Exception ex) { ErrorData.currentDataType = ErrorData.DataType.text; ErrorData.currentErrorType = ErrorData.ErrorType.ConnectionError; @@ -47,21 +49,24 @@ public static boolean run() throws Exception { ErrorData.bytes = response; throw ex; } - + XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); - + try { if (!xpath.evaluate("/response/header/error/code", doc).equals("0")) { ErrorData.currentErrorType = ErrorData.ErrorType.PrivateFairyBattleResponse; ErrorData.currentDataType = ErrorData.DataType.text; - ErrorData.text = xpath.evaluate("/response/header/error/message", doc); + ErrorData.text = xpath.evaluate( + "/response/header/error/message", doc); return false; } - if (Process.info.LatestFairyList.size() > 1000) Process.info.LatestFairyList.poll(); + if (Process.info.LatestFairyList.size() > 1000) + Process.info.LatestFairyList.poll(); Process.info.LatestFairyList.offer(Process.info.fairy); - - if ((boolean)xpath.evaluate("count(//private_fairy_top) > 0", doc, XPathConstants.BOOLEAN)) { + + if ((boolean) xpath.evaluate("count(//private_fairy_top) > 0", doc, + XPathConstants.BOOLEAN)) { Process.info.events.push(Info.EventType.fairyBattleEnd); return true; } @@ -69,42 +74,54 @@ public static boolean run() throws Exception { ParseCardList.parse(doc); if (xpath.evaluate("//battle_result/winner", doc).equals("1")) { Process.info.events.push(Info.EventType.fairyBattleWin); + Process.info.OwnFairyKilled = true; } else { Process.info.events.push(Info.EventType.fairyBattleLose); + Process.info.OwnFairyKilled = false; } - - //Process.info.fairy.FairyName = xpath.evaluate("//battle_vs_info/player[last()]/name", doc); + + // Process.info.fairy.FairyName = + // xpath.evaluate("//battle_vs_info/player[last()]/name", doc); Process.info.SetTimeoutByAction(Name); - - String spec = xpath.evaluate("//private_fairy_reward_list/special_item/after_count", doc); + + String spec = xpath + .evaluate( + "//private_fairy_reward_list/special_item/after_count", + doc); if (spec.length() != 0) { Process.info.gather = Integer.parseInt(spec); } else { Process.info.gather = -1; } - + // 检查觉醒 - if ((boolean)xpath.evaluate("count(//ex_fairy/rare_fairy)>0", doc, XPathConstants.BOOLEAN)) { + if ((boolean) xpath.evaluate("count(//ex_fairy/rare_fairy)>0", doc, + XPathConstants.BOOLEAN)) { // Yes - Process.info.fairy.Type = FairyBattleInfo.PRIVATE | FairyBattleInfo.SELF | FairyBattleInfo.RARE; - Process.info.fairy.FairyLevel = xpath.evaluate("//ex_fairy/rare_fairy/lv", doc); - Process.info.fairy.SerialId = xpath.evaluate("//ex_fairy/rare_fairy/serial_id", doc); - Process.info.fairy.UserId = xpath.evaluate("//ex_fairy/rare_fairy/discoverer_id", doc); - Process.info.fairy.fairyCurrHp = Integer.parseInt(xpath.evaluate("//ex_fairy/rare_fairy/hp", doc)); - Process.info.fairy.fairyMaxHp = Integer.parseInt(xpath.evaluate("//ex_fairy/rare_fairy/hp_max", doc)); + Process.info.fairy.Type = FairyBattleInfo.PRIVATE + | FairyBattleInfo.SELF | FairyBattleInfo.RARE; + Process.info.fairy.FairyLevel = xpath.evaluate( + "//ex_fairy/rare_fairy/lv", doc); + Process.info.fairy.SerialId = xpath.evaluate( + "//ex_fairy/rare_fairy/serial_id", doc); + Process.info.fairy.UserId = xpath.evaluate( + "//ex_fairy/rare_fairy/discoverer_id", doc); + Process.info.fairy.fairyCurrHp = Integer.parseInt(xpath + .evaluate("//ex_fairy/rare_fairy/hp", doc)); + Process.info.fairy.fairyMaxHp = Integer.parseInt(xpath + .evaluate("//ex_fairy/rare_fairy/hp_max", doc)); + Process.info.fairy.No = Info.PrivateFairyBattleRare.No; Process.info.events.push(Info.EventType.fairyTransform); } - - } catch (Exception ex) { - if (ErrorData.currentErrorType != ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType != ErrorData.ErrorType.none) + throw ex; ErrorData.currentDataType = ErrorData.DataType.bytes; ErrorData.currentErrorType = ErrorData.ErrorType.PrivateFairyBattleDataParseError; ErrorData.bytes = response; throw ex; } - + return true; - } } diff --git a/action/RecvPFBGood.java b/src/action/RecvPFBGood.java similarity index 100% rename from action/RecvPFBGood.java rename to src/action/RecvPFBGood.java diff --git a/action/SellCard.java b/src/action/SellCard.java similarity index 100% rename from action/SellCard.java rename to src/action/SellCard.java diff --git a/action/Use.java b/src/action/Use.java similarity index 100% rename from action/Use.java rename to src/action/Use.java diff --git a/info/Area.java b/src/info/Area.java similarity index 93% rename from info/Area.java rename to src/info/Area.java index 9fec9f9..4e63b7b 100644 --- a/info/Area.java +++ b/src/info/Area.java @@ -6,6 +6,7 @@ public class Area { public int minAP = Integer.MAX_VALUE; public int maxAP = Integer.MIN_VALUE; public int exploreProgress = 0; + public int areaType = 0; public Area() { diff --git a/src/info/Box.java b/src/info/Box.java new file mode 100644 index 0000000..26ec8db --- /dev/null +++ b/src/info/Box.java @@ -0,0 +1,7 @@ +package info; + +public class Box { + public String boxId = ""; + public int boxType = 1; + public boolean exist = true; +} diff --git a/info/Card.java b/src/info/Card.java similarity index 93% rename from info/Card.java rename to src/info/Card.java index f6a6903..e4734e3 100644 --- a/info/Card.java +++ b/src/info/Card.java @@ -10,4 +10,5 @@ public class Card { public int lvMax = 0; public int plusLimit = 0; public boolean exist = true; + public int price; } diff --git a/info/Deck.java b/src/info/Deck.java similarity index 100% rename from info/Deck.java rename to src/info/Deck.java diff --git a/info/FairyBattleInfo.java b/src/info/FairyBattleInfo.java similarity index 84% rename from info/FairyBattleInfo.java rename to src/info/FairyBattleInfo.java index 8517c51..d85cfd4 100644 --- a/info/FairyBattleInfo.java +++ b/src/info/FairyBattleInfo.java @@ -4,8 +4,12 @@ public class FairyBattleInfo { public String GuildId = ""; public String UserId = ""; public String SerialId = ""; - public String No = "2"; - public final String Spp = "dummy"; + public String No = ""; + public String Spp = "dummy"; + public String battle_contribution = ""; + public String hp_contribution = ""; + public String attack_compensation = ""; + public String contribution = ""; public static final int RARE = 0x1; public static final int SELF = 0x2; @@ -22,7 +26,7 @@ public class FairyBattleInfo { public String FairyName = ""; public String FairyLevel = ""; public String Finder = ""; - + public int fairyCurrHp = 0; public int fairyMaxHp = 0; diff --git a/info/FairySelectUser.java b/src/info/FairySelectUser.java similarity index 100% rename from info/FairySelectUser.java rename to src/info/FairySelectUser.java diff --git a/info/Floor.java b/src/info/Floor.java similarity index 87% rename from info/Floor.java rename to src/info/Floor.java index 76db47a..aa38f3b 100644 --- a/info/Floor.java +++ b/src/info/Floor.java @@ -6,5 +6,6 @@ public class Floor { public String type = ""; public int progress = 0; public int cost = 0; + public boolean innerFlag = false; //public String bossId = "";估计和秘境守护者有关,暂时先放着 } diff --git a/info/PFBGood.java b/src/info/PFBGood.java similarity index 100% rename from info/PFBGood.java rename to src/info/PFBGood.java diff --git a/src/info/PartyInfo.java b/src/info/PartyInfo.java new file mode 100644 index 0000000..34b76c4 --- /dev/null +++ b/src/info/PartyInfo.java @@ -0,0 +1,17 @@ +package info; + +import java.util.ArrayList; + +public class PartyInfo { + + // guild_info + public static String user_rank = ""; + public static String user_hunting_point = ""; + public static String own_guild_point = ""; + public static String own_guild_dairy_point = ""; + public static String own_guild_rank = ""; + public static String rival_guild_point = ""; + public static String rival_guild_dairy_point = ""; + public static String rival_guild_rank = ""; + public static ArrayList ranklist = new ArrayList(); +} diff --git a/src/info/PlayerRank.java b/src/info/PlayerRank.java new file mode 100644 index 0000000..3173cbb --- /dev/null +++ b/src/info/PlayerRank.java @@ -0,0 +1,27 @@ +package info; + +public class PlayerRank implements Comparable { + public int ilv; + public int irank; + public String logintime = ""; + public String name = ""; + public int point; + + @Override + public int compareTo(PlayerRank other) { + if (other == null) { + return 1; + } + int num = other.point - this.point; + if (num == 0) { + num = this.ilv - other.ilv; + } + return num; + } + + @Override + public String toString() { + return String.format("%s,等级:%d,贡献:%d,排名:%d,最后登录:%s\r\n", this.name, + this.ilv, this.point, this.irank, this.logintime); + } +} diff --git a/net/Crypto.java b/src/net/Crypto.java similarity index 100% rename from net/Crypto.java rename to src/net/Crypto.java diff --git a/net/HttpResponseHandler.java b/src/net/HttpResponseHandler.java similarity index 100% rename from net/HttpResponseHandler.java rename to src/net/HttpResponseHandler.java diff --git a/net/Network.java b/src/net/Network.java similarity index 100% rename from net/Network.java rename to src/net/Network.java diff --git a/src/walker/ErrorData.java b/src/walker/ErrorData.java new file mode 100644 index 0000000..71b039d --- /dev/null +++ b/src/walker/ErrorData.java @@ -0,0 +1,63 @@ +package walker; + +/** + * 处理内部错误,在execute时,如果是run所捕获的错误,则放入此类中。 这样,当execute捕获到错误时,首先检查此类中有无存放错误信息, + * 如果有,则转入错误信息处理; 如果没有,则说明是其他位置的异常,另行处理。 + */ +public class ErrorData { + + public enum DataType { + bytes, text, none + } + + public static DataType currentDataType = DataType.none; + public static ErrorType currentErrorType = ErrorType.none; + public static byte[] bytes; + public static String text; + + public enum ErrorType { + // 总体 + none, ConnectionError, + // 登录 + LoginDataError, LoginDataParseError, LoginResponse, + // 获取地图 + AreaDataError, AreaDataParseError, AreaResponse, + // 上街 + GotoFloorDataError, GotoFloorDataParseError, GotoFloorResponse, + // 获取妖精列表 + FairyListDataError, FairyListDataParseError, FairyListResponse, + // 妖精战斗 + PrivateFairyBattleDataError, PrivateFairyBattleDataParseError, PrivateFairyBattleResponse, + // 探索 + ExploreDataError, ExploreDataParseError, ExploreResponse, + // 外敌界面 + GuildTopDataError, GuildTopDataParseError, GuildTopResponse, + // 外敌战 + GuildBattleDataError, GuildBattleDataParseError, GuildBattleResponse, + // 获取妖精站礼物 + GetFairyRewardDataError, GetFairyRewardResponse, + // 取箱 + GetRewardBoxDataError, GetRewardBoxReponse, + // 卖卡 + SellCardDataError, SellCardResponse, + // 升级 + LvUpDataError, LvUpResponse, + // 赞 + PFB_GoodDataError, PFB_GoodResponse, + // fairy_history + FairyHistoryDataError, FairyHistoryDataParseError, FairyHistoryResponse, + // 收赞 + RecvPFBGoodDataError, RecvPFBGoodDataParseError, RecvPFBGoodResponse, + // 吃药 + UseDataError, UseResponse, + //团贡 + PartyRankDataError, PartyRankDataParseError, PartyRankResponse + } + + public static void clear() { + bytes = null; + text = null; + currentDataType = DataType.none; + currentErrorType = ErrorType.none; + } +} diff --git a/src/walker/GetConfig.java b/src/walker/GetConfig.java new file mode 100644 index 0000000..7bd51db --- /dev/null +++ b/src/walker/GetConfig.java @@ -0,0 +1,146 @@ +package walker; + +import java.util.ArrayList; + +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; + +import net.Network; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class GetConfig { + public static void parse(Document doc) throws Exception { + try { + XPathFactory factory = XPathFactory.newInstance(); + XPath xpath = factory.newXPath(); + + Info.LoginId = xpath.evaluate("/config/username", doc); + Info.LoginPw = xpath.evaluate("/config/password", doc); + Network.UserAgent = xpath.evaluate("/config/user_agent", doc); + + NodeList idl = (NodeList) xpath.evaluate("/config/sell_card/id", + doc, XPathConstants.NODESET); + Info.CanBeSold = new ArrayList(); + for (int i = 0; i < idl.getLength(); i++) { + Node idx = idl.item(i); + try { + Info.CanBeSold.add(idx.getFirstChild().getNodeValue()); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + Info.FairyBattleFirst = xpath.evaluate( + "/config/option/fairy_battle_first", doc).equals("1"); + Info.AllowBCInsuffient = xpath.evaluate( + "/config/option/allow_bc_insuffient", doc).equals("1"); + Info.MinAPOnly = xpath.evaluate("/config/option/min_ap_only", doc) + .equals("1"); + Info.AutoAddp = Integer.parseInt(xpath.evaluate( + "/config/option/auto_add_point", doc)); + Info.AllowAttackSameFairy = xpath.evaluate( + "/config/option/allow_attack_same_fairy", doc).equals("1"); + Info.debug = xpath.evaluate("/config/option/debug", doc) + .equals("1"); + Info.receiveBattlePresent = xpath.evaluate( + "/config/option/receive_battle_present", doc).equals("1"); + Info.GoStop = xpath.evaluate("/config/option/go_stop", doc).equals( + "1"); + Info.SpecilInstance = xpath.evaluate( + "/config/option/specil_instance", doc).equals("1"); + Info.InnerInstance = xpath.evaluate( + "/config/option/inner_instance", doc).equals("1"); + Info.receiveBox = xpath.evaluate("/config/option/receive_box", doc) + .equals("1"); + Info.partyrank = xpath.evaluate("/config/option/partyrank", doc) + .equals("1"); + Info.InnerMapNo = Integer.valueOf(xpath.evaluate( + "/config/option/first_inner_map", doc)); + Info.autoSellCard = xpath.evaluate("/config/sell_card/enable", doc) + .equals("1"); + + Info.autoUseAp = xpath.evaluate("/config/use/auto_use_ap", doc) + .equals("1"); + + if (Info.autoUseAp) { + String half = xpath.evaluate("/config/use/strategy/ap/half", + doc); + if (half.equals("0")) { + Info.autoApType = Info.autoUseType.FULL_ONLY; + } else if (half.equals("1")) { + Info.autoApType = Info.autoUseType.HALF_ONLY; + } else { + Info.autoApType = Info.autoUseType.ALL; + } + Info.autoApLow = Integer.parseInt(xpath.evaluate( + "/config/use/strategy/ap/low", doc)); + Info.autoApFullLow = Integer.parseInt(xpath.evaluate( + "/config/use/strategy/ap/full_low", doc)); + } + Info.autoUseBc = xpath.evaluate("/config/use/auto_use_bc", doc) + .equals("1"); + if (Info.autoUseBc) { + String half = xpath.evaluate("/config/use/strategy/bc/half", + doc); + if (half.equals("0")) { + Info.autoBcType = Info.autoUseType.FULL_ONLY; + } else if (half.equals("1")) { + Info.autoBcType = Info.autoUseType.HALF_ONLY; + } else { + Info.autoBcType = Info.autoUseType.ALL; + } + Info.autoBcLow = Integer.parseInt(xpath.evaluate( + "/config/use/strategy/bc/low", doc)); + Info.autoBcFullLow = Integer.parseInt(xpath.evaluate( + "/config/use/strategy/bc/full_low", doc)); + } + + Info.FriendFairyBattleRare.No = xpath + .evaluate( + "/config/deck/deck_profile[name='FriendFairyBattleRare']/no", + doc); + Info.FriendFairyBattleRare.BC = Integer + .parseInt(xpath + .evaluate( + "/config/deck/deck_profile[name='FriendFairyBattleRare']/bc", + doc)); + + Info.FriendFairyBattleNormal.No = xpath + .evaluate( + "/config/deck/deck_profile[name='FriendFairyBattleNormal']/no", + doc); + Info.FriendFairyBattleNormal.BC = Integer + .parseInt(xpath + .evaluate( + "/config/deck/deck_profile[name='FriendFairyBattleNormal']/bc", + doc)); + + Info.PublicFairyBattle.BC = Integer + .parseInt(xpath + .evaluate( + "/config/deck/deck_profile[name='GuildFairyDeck']/bc", + doc)); + Info.PublicFairyBattle.No = xpath.evaluate( + "/config/deck/deck_profile[name='GuildFairyDeck']/no", doc); + + Info.PrivateFairyBattleNormal.No = xpath.evaluate( + "/config/deck/deck_profile[name='FairyDeck']/no", doc); + Info.PrivateFairyBattleNormal.BC = Integer.parseInt(xpath.evaluate( + "/config/deck/deck_profile[name='FairyDeck']/bc", doc)); + + Info.PrivateFairyBattleRare.No = xpath.evaluate( + "/config/deck/deck_profile[name='RareFairyDeck']/no", doc); + Info.PrivateFairyBattleRare.BC = Integer.parseInt(xpath.evaluate( + "/config/deck/deck_profile[name='RareFairyDeck']/bc", doc)); + } catch (Exception ex) { + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) { + throw ex; + } + } + + } +} diff --git a/walker/Go.java b/src/walker/Go.java similarity index 71% rename from walker/Go.java rename to src/walker/Go.java index dfd1a50..c542f5e 100644 --- a/walker/Go.java +++ b/src/walker/Go.java @@ -12,7 +12,7 @@ public class Go { public static void main(String[] args) { - if (args.length < 1) { + if (args.length < 1) { printHelp(); return; } @@ -25,23 +25,18 @@ public static void main(String[] args) { if (args.length < 3) { System.out.println(Version.strVersion()); System.out.println(Version.strThanks()); - Go.log(String.format("Read cards that can be sold (%d).", Info.CanBeSold.size())); + System.out.println(Version.strInfo()); + Go.log(String.format("Read cards that can be sold (%d).", + Info.CanBeSold.size())); } if (args.length == 1) { // auto mode while (true) { Process proc = new Process(); - Profile2 prof = new Profile2(); - while(true) { + + while (true) { try { - switch (Info.Profile) { - case 1: - proc.auto(); - break; - case 2: - prof.auto(); - break; - } + proc.auto(); } catch (Exception ex) { boolean printed = false; if (ex.getMessage() != null) { @@ -64,6 +59,8 @@ public static void main(String[] args) { } Process.info.events.add(EventType.cookieOutOfDate); Go.log("[Global] Restart"); + + break; } } } @@ -79,9 +76,11 @@ public static void main(String[] args) { try { if (args[1].startsWith("-f")) { if (args[1].charAt(2) == '1') { - System.out.println(new String(Crypto.DecryptNoKey(ReadFileAll(args[2])))); + System.out.println(new String(Crypto + .DecryptNoKey(ReadFileAll(args[2])))); } else if (args[1].charAt(2) == '2') { - System.out.println(new String(Crypto.DecryptWithKey(ReadFileAll(args[2])))); + System.out.println(new String(Crypto + .DecryptWithKey(ReadFileAll(args[2])))); } } else if (args[1].equals("-t")) { // 用作测试使用 @@ -91,9 +90,11 @@ public static void main(String[] args) { } } else if (args[1].startsWith("-d")) { if (args[1].charAt(2) == '1') { - System.out.println(new String(Crypto.DecryptBase64NoKey2Str(args[2]))); + System.out.println(new String(Crypto + .DecryptBase64NoKey2Str(args[2]))); } else if (args[1].charAt(2) == '2') { - System.out.println(new String(Crypto.DecryptBase64WithKey2Str(args[2]))); + System.out.println(new String(Crypto + .DecryptBase64WithKey2Str(args[2]))); } } } catch (Exception ex) { @@ -108,32 +109,37 @@ public static void main(String[] args) { public static void printHelp() { System.out.println(Version.strVersion()); System.out.println(Version.strThanks()); - System.out.println("Usage: config_xml [-h][-f[1|2] file][-d[1|2] str][-m]"); + System.out.println(Version.strInfo()); + System.out + .println("Usage: config_xml [-h][-f[1|2] file][-d[1|2] str][-m]"); } public static void log(String message) { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 - if (message == null || message.isEmpty()) return; - if (message.length() > 147) message = message.substring(0, 147) + "..."; + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式 + if (message == null || message.isEmpty()) + return; + if (message.length() > 147) + message = message.substring(0, 147) + "..."; if (!message.contains("\n")) { System.out.print(df.format(new Date()));// new Date()为获取当前系统时间 - System.out.println("> "+ message); + System.out.println("> " + message); return; } for (String l : message.split("\n")) { System.out.print(df.format(new Date())); - System.out.println("> "+ l); + System.out.println("> " + l); } } - - public static byte[] ReadFileAll(String path) throws Exception{ + + public static byte[] ReadFileAll(String path) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); InputStream is = null; try { is = new FileInputStream(path); byte[] b = new byte[0x2800]; int n; - while ((n = is.read(b)) != -1) baos.write(b, 0, n); + while ((n = is.read(b)) != -1) + baos.write(b, 0, n); } catch (Exception ex) { throw ex; } finally { @@ -141,15 +147,12 @@ public static byte[] ReadFileAll(String path) throws Exception{ if (is != null) { is.close(); } - } catch (Exception ex){ + } catch (Exception ex) { throw ex; } } - //System.out.println(baos.toByteArray().length); + // System.out.println(baos.toByteArray().length); return baos.toByteArray(); } - - - } diff --git a/walker/Info.java b/src/walker/Info.java similarity index 68% rename from walker/Info.java rename to src/walker/Info.java index c5acd0a..9131216 100644 --- a/walker/Info.java +++ b/src/walker/Info.java @@ -1,7 +1,7 @@ - package walker; import info.Area; +import info.Box; import info.Card; import info.Deck; import info.FairyBattleInfo; @@ -15,17 +15,17 @@ import java.util.LinkedList; import java.util.Queue; import java.util.Stack; +import java.util.TreeMap; import action.ActionRegistry; public class Info { // INFO: static variants are need to be configured in configure file - + // login info public static String LoginId = ""; public static String LoginPw = ""; - public static int Profile = 1; - + // user info public String username = ""; public int ap = 0; @@ -49,23 +49,36 @@ public class Info { public int apUp = 0; public int bcUp = 0; public long money = 0; - + /** * 优先进行妖精战 */ public static boolean FairyBattleFirst = true; + public boolean OwnFairyKilled = true; + /** + * 遇敌停步 + */ + public static boolean GoStop = true; /** * 允许deck不满足的情况下依旧走图和攻击 */ public static boolean AllowBCInsuffient = false; /** - * 只走cost1的图 + * 秘境开关 */ - public static boolean OneAPOnly = false; + public static boolean MinAPOnly = false; + public static boolean InnerInstance = true; + public static boolean SpecilInstance = true; + + /** + * 第一张里图编号 + */ + public static int InnerMapNo = 100000; + /** * 自动加点 */ - public static boolean AutoAddp = true; + public static int AutoAddp = 0; /** * 允许舔同一个怪 */ @@ -74,71 +87,96 @@ public class Info { * debug输出xml */ public static boolean debug = false; - /** - * night mode 开关 - */ - public static boolean nightModeSwitch = true; - + /** * 自动收集妖精战礼物 */ public static boolean receiveBattlePresent = true; - - // 吃药相关的开关 + /** + * 骑士团战斗标记 + */ + public boolean GuildBattleFlag = false; + + /** + * 查询团贡 + */ + public static boolean partyrank = false; + + /** + * 计数器 + */ + public int count1 = 0; + public int count2 = 0; + public int count3 = 0; + + /** + * 自动收箱子 + */ + public static boolean receiveBox = true; + + /** + * 自动卖卡 + */ + public static boolean autoSellCard = true; + + /** + * 吃药相关的开关 + */ public static boolean autoUseAp = true; public static boolean autoUseBc = true; + public enum autoUseType { - HALF_ONLY, - FULL_ONLY, - ALL + HALF_ONLY, FULL_ONLY, ALL } + public static autoUseType autoApType = autoUseType.HALF_ONLY; public static autoUseType autoBcType = autoUseType.HALF_ONLY; public static int autoApLow = 1; public static int autoBcLow = 50; public static int autoApFullLow = 10; public static int autoBcFullLow = 10; - + // card list public ArrayList cardList; public static ArrayList CanBeSold = new ArrayList(); public static ArrayList KeepCard; public String toSell = ""; - + + // box list + public ArrayList boxList; + public String toGet = ""; + // deck public static Deck FriendFairyBattleRare = new Deck(); public static Deck PublicFairyBattle = new Deck(); public static Deck PrivateFairyBattleNormal = new Deck(); public static Deck PrivateFairyBattleRare = new Deck(); public static Deck FriendFairyBattleNormal = new Deck(); - - + // area - public Hashtable area; + public Hashtable area; public boolean InnerMap = false; - - + // floor - public Hashtable floor; + public TreeMap floor; public Floor front; public boolean AllClear = false; - + // fairy public FairyBattleInfo fairy; public FairyBattleInfo gfairy; public boolean NoFairy = false; public Queue LatestFairyList = new LinkedList(); public Stack PFBGoodList; - public Hashtable FairySelectUserList; - + public Hashtable FairySelectUserList; + // explore public String ExploreResult = ""; public String ExploreProgress = ""; public String ExploreGold = ""; public String ExploreExp = ""; - - - //吃药相关 + + // 吃药相关 public int fullBc = 0; public int fullAp = 0; public int halfBc = 0; @@ -146,27 +184,25 @@ public enum autoUseType { public int halfBcToday = 0; public int halfApToday = 0; public String toUse = ""; - - + // timeout public enum TimeoutEntry { - apbc, - fairy, - login, - reward, - map, - ticket, + apbc, fairy, login, reward, map, ticket, } - private Hashtable timeout; + + private Hashtable timeout; + public long GetTimeout(TimeoutEntry te) { return System.currentTimeMillis() - timeout.get(te); } + public void SetTimeoutByEntry(TimeoutEntry te) { timeout.put(te, System.currentTimeMillis()); } + public void SetTimeoutByAction(ActionRegistry.Action act) { switch (act) { - case LOGIN: + case LOGIN: this.SetTimeoutByEntry(TimeoutEntry.fairy); this.SetTimeoutByEntry(TimeoutEntry.login); case PRIVATE_FAIRY_BATTLE: @@ -189,68 +225,53 @@ public void SetTimeoutByAction(ActionRegistry.Action act) { break; } } + public ArrayList CheckTimeout() { ArrayList te = new ArrayList(); - if (GetTimeout(TimeoutEntry.apbc) > 180000) te.add(TimeoutEntry.apbc); - if (GetTimeout(TimeoutEntry.fairy) > 60000) te.add(TimeoutEntry.fairy); + if (GetTimeout(TimeoutEntry.apbc) > 180000) + te.add(TimeoutEntry.apbc); + if (GetTimeout(TimeoutEntry.fairy) > 60000) + te.add(TimeoutEntry.fairy); if (Calendar.getInstance().get(Calendar.HOUR_OF_DAY) == 1) { - if (GetTimeout(TimeoutEntry.login) > 3600000) te.add(TimeoutEntry.login); + if (GetTimeout(TimeoutEntry.login) > 3600000) + te.add(TimeoutEntry.login); } - if (GetTimeout(TimeoutEntry.reward) > 86400000l) te.add(TimeoutEntry.reward); - if (GetTimeout(TimeoutEntry.map) > 86400000l) te.add(TimeoutEntry.map); - if (GetTimeout(TimeoutEntry.ticket) > 600000) te.add(TimeoutEntry.ticket); + if (GetTimeout(TimeoutEntry.reward) > 86400000l) + te.add(TimeoutEntry.reward); + if (GetTimeout(TimeoutEntry.map) > 86400000l) + te.add(TimeoutEntry.map); + if (GetTimeout(TimeoutEntry.ticket) > 600000) + te.add(TimeoutEntry.ticket); return te; } - + // event public enum EventType { - notLoggedIn, - cookieOutOfDate, - needFloorInfo, - innerMapJump, - areaComplete, - fairyAppear, - fairyTransform, - fairyReward, - fairyCanBattle, - fairyBattleWin, - fairyBattleLose, - fairyBattleEnd, - cardFull, - privateFairyAppear, - guildTopRetry, - guildBattle, - guildTop, - ticketFull, - getFairyReward, - needAPBCInfo, - levelUp, - PFBGood, - recvPFBGood, gotoFloor + notLoggedIn, cookieOutOfDate, needFloorInfo, innerMapJump, areaComplete, fairyAppear, fairyTransform, fairyReward, fairyCanBattle, fairyBattleWin, fairyBattleLose, fairyBattleEnd, cardFull, privateFairyAppear, guildTopRetry, guildBattle, guildTop, ticketFull, getFairyReward, needAPBCInfo, levelUp, PFBGood, recvPFBGood, gotoFloor } + public Stack events; - - + public Info() { cardList = new ArrayList(); - area = new Hashtable(); - floor = new Hashtable(); + area = new Hashtable(); + floor = new TreeMap(); front = new Floor(); PFBGoodList = new Stack(); events = new Stack(); events.push(EventType.notLoggedIn); KeepCard = new ArrayList(); - FairySelectUserList = new Hashtable(); - - timeout = new Hashtable(); + FairySelectUserList = new Hashtable(); + + timeout = new Hashtable(); timeout.put(TimeoutEntry.apbc, (long) 0); timeout.put(TimeoutEntry.fairy, (long) 0); timeout.put(TimeoutEntry.login, (long) 0); timeout.put(TimeoutEntry.reward, (long) 0); timeout.put(TimeoutEntry.map, (long) 0); - + fairy = new FairyBattleInfo(); gfairy = new FairyBattleInfo(); } - + } diff --git a/walker/Process.java b/src/walker/Process.java similarity index 54% rename from walker/Process.java rename to src/walker/Process.java index 0a47e77..802a2bc 100644 --- a/walker/Process.java +++ b/src/walker/Process.java @@ -8,6 +8,8 @@ import java.io.StringWriter; import java.util.ArrayList; import java.util.List; +import java.text.SimpleDateFormat; +import java.util.Date; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -19,6 +21,7 @@ import com.sun.org.apache.xml.internal.serialize.OutputFormat; import com.sun.org.apache.xml.internal.serialize.XMLSerializer; +import walker.Process; import walker.Info.TimeoutEntry; import action.ActionRegistry.Action; import action.AddArea; @@ -26,12 +29,15 @@ import action.GetFairyList; import action.GetFairyReward; import action.GetFloorInfo; +import action.GetRank; +import action.GetRewardBox; import action.GotoFloor; import action.GuildBattle; import action.GuildTop; import action.Login; import action.LvUp; import action.PFBGood; +import action.PartyRank; import action.PrivateFairyBattle; import action.RecvPFBGood; import action.SellCard; @@ -40,12 +46,12 @@ public class Process { public static Info info; public static Network network; - + public Process() { info = new Info(); network = new Network(); } - + public void auto() throws Exception { try { if (ErrorData.currentErrorType != ErrorData.ErrorType.none) { @@ -54,20 +60,26 @@ public void auto() throws Exception { long start = System.currentTimeMillis(); execute(Think.doIt(getPossibleAction())); long delta = System.currentTimeMillis() - start; - if (delta < 5000) Thread.sleep(5000 - delta); - if (Info.nightModeSwitch && info.events.empty() && info.NoFairy) Thread.sleep(600000); // 半夜速度慢点 + + if (delta < 5000) { + Thread.sleep(5000 - delta); + } + + if (info.events.empty() && info.NoFairy) { + Thread.sleep(30000); + } } } catch (Exception ex) { throw ex; } } - + private void rescue() { Go.log(ErrorData.currentErrorType.toString()); switch (ErrorData.currentDataType) { case bytes: if (ErrorData.bytes != null) { - Go.log(new String(ErrorData.bytes)); + Go.log(new String(ErrorData.bytes)); } else { Go.log("Set type to byte, but no message"); } @@ -80,11 +92,11 @@ private void rescue() { } ErrorData.clear(); } - + private List getPossibleAction() { ArrayList result = new ArrayList(); if (info.events.size() != 0) { - switch(info.events.pop()) { + switch (info.events.pop()) { case notLoggedIn: case cookieOutOfDate: result.add(Action.LOGIN); @@ -96,17 +108,31 @@ private List getPossibleAction() { result.add(Action.PRIVATE_FAIRY_BATTLE); break; case fairyReward: - if (info.ticket > 0) { + if (info.ticket > 10) { result.add(Action.GUILD_TOP); } else if (info.ticket < 0) { Go.log("Keep reward"); } else { - result.add(Action.GET_FAIRY_REWARD); + try { + if (GetFairyReward.run()) { + Go.log(ErrorData.text); + ErrorData.clear(); + + if (Info.receiveBox == true) { + GetRewardBox.list(); + if (Process.info.boxList.size() >= 650) + GetRewardBox.get(); + } + } + } catch (Exception ex) { + } } break; case innerMapJump: Go.log("Map Status Changed!"); - case needFloorInfo: + result.add(Action.GET_FLOOR_INFO); + break; + case needFloorInfo: result.add(Action.GET_FLOOR_INFO); break; case areaComplete: @@ -121,7 +147,16 @@ private List getPossibleAction() { case getFairyReward: break; case guildBattle: - result.add(Action.GUILD_BATTLE); + if (info.bc == info.bcMax && info.ticket < 15) + break; + if (info.gfairy.Spp.equals("使用BC3%回復")) { + result.add(Action.GUILD_BATTLE); + } else if (info.ticket >= 15) { + result.add(Action.GUILD_BATTLE); + } else if (!Process.info.gfairy.UserId + .equals(Process.info.username)) { + result.add(Action.GUILD_BATTLE); + } break; case guildTopRetry: case guildTop: @@ -132,14 +167,15 @@ private List getPossibleAction() { result.add(Action.GOTO_FLOOR); break; case levelUp: - if (Info.AutoAddp == false) { - //Go.log("自动加点已关闭"); + if (Info.AutoAddp == 0) { + // 输出次数太多,屏蔽掉 + // Go.log("自动加点已关闭"); } else { - result.add(Action.LV_UP); + result.add(Action.LV_UP); } case fairyBattleEnd: case fairyBattleLose: - case fairyBattleWin: + case fairyBattleWin: break; case PFBGood: result.add(Action.PFB_GOOD); @@ -151,8 +187,12 @@ private List getPossibleAction() { result.add(Action.GOTO_FLOOR); break; } - if (!result.isEmpty()) return result; + + if (!result.isEmpty()) { + return result; + } } + ArrayList te = info.CheckTimeout(); for (TimeoutEntry e : te) { switch (e) { @@ -169,30 +209,70 @@ private List getPossibleAction() { Process.info.events.push(Info.EventType.needFloorInfo); break; case ticket: - if (info.ticket > 0) Process.info.events.push(Info.EventType.cardFull); + if (info.ticket > 0) + Process.info.events.push(Info.EventType.cardFull); break; case reward: default: break; - } + } } - result.add(Action.EXPLORE); + + if (!Process.info.OwnFairyKilled && Info.GoStop + && (info.ap < info.apMax || info.lv < 30)) { + Process.info.count1++; + if (Process.info.count1 < 5) { + result.add(Action.GET_FAIRY_LIST); + Go.log("sleeping......"); + } else { + Process.info.count1 = 0; + } + try { + Thread.sleep(15000); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } else { + result.add(Action.EXPLORE); + } + + result.add(Action.SELL_CARD); result.add(Action.USE); - // result.add(Action.GOTO_FLOOR); - if (Info.FairyBattleFirst) result.add(Action.GET_FAIRY_LIST); + + if (Info.FairyBattleFirst) { + result.add(Action.GET_FAIRY_LIST); + } + return result; } - + private void execute(Action action) throws Exception { switch (action) { case LOGIN: try { if (Login.run()) { - Go.log(String.format("User: %s, AP: %d/%d, BC: %d/%d, Card: %d/%d, ticket: %d, money: %d", - info.username, info.ap, info.apMax, info.bc, info.bcMax, - info.cardList.size(), info.cardMax, info.ticket, info.money)); + Go.log(String + .format("玩家: %s, AP: %d/%d, BC: %d/%d, Card: %d/%d, ticket: %d, money: %d", + info.username, info.ap, info.apMax, + info.bc, info.bcMax, info.cardList.size(), + info.cardMax, info.ticket, info.money)); info.events.push(Info.EventType.fairyAppear); info.events.push(Info.EventType.needFloorInfo); + + int gatherRank = GetRank.gatherrank( + Integer.parseInt(info.userId), 5); + int guildRank = GetRank.gatherrank( + Integer.parseInt(info.userId), 4); + + Go.log(String.format("收集排名: %d, 骑士团个人排名: %d", gatherRank, + guildRank)); + + if (Info.partyrank) + PartyRank.run(); + + if (Info.receiveBox == true) + Login.listRewardbox(); + } else { info.events.push(Info.EventType.notLoggedIn); } @@ -206,52 +286,56 @@ private void execute(Action action) throws Exception { case GET_FLOOR_INFO: try { if (GetFloorInfo.run()) { - if (Process.info.AllClear) Process.info.front = Process.info.floor.get(1); - Go.log(String.format("Area(%d) Front: %s>%s@c=%d", - info.area.size(), - info.area.get(Integer.parseInt(info.front.areaId)).areaName, - info.front.floorId, - info.front.cost)); + // if (Process.info.AllClear | Info.MinAPOnly) + // Process.info.front = Process.info.floor.firstEntry() + // .getValue(); + Go.log(String.format( + "Area:%s Floor:%s层 消耗=%d", + info.area.get(Integer.parseInt(info.front.areaId)).areaName, + info.front.floorId, info.front.cost)); } - + } catch (Exception ex) { if (ex.getMessage() != null && ex.getMessage().equals("302")) { info.events.push(Info.EventType.innerMapJump); ErrorData.clear(); } else { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } } break; case ADD_AREA: try { if (AddArea.run()) { - Go.log(String.format("Area(%d) Front: %s>%s@c=%d", - info.area.size(), - info.area.get(Integer.parseInt(info.front.areaId)).areaName, - info.front.floorId, - info.front.cost)); + Go.log(String.format( + "Area:%s Floor:%s层 消耗=%d", + info.area.get(Integer.parseInt(info.front.areaId)).areaName, + info.front.floorId, info.front.cost)); } - + } catch (Exception ex) { if (ex.getMessage().equals("302")) { info.events.push(Info.EventType.innerMapJump); ErrorData.clear(); } else { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } } break; case GET_FAIRY_LIST: try { if (GetFairyList.run()) { - if (!info.events.empty() && info.events.peek() == Info.EventType.fairyCanBattle) { + if (!info.events.empty() + && info.events.peek() == Info.EventType.fairyCanBattle) { Go.log("Other's fairy found!"); } else { Go.log("No fairy found."); } } else { - if (Info.FairyBattleFirst) info.events.push(Info.EventType.fairyAppear); + if (Info.FairyBattleFirst) + info.events.push(Info.EventType.fairyAppear); } } catch (Exception ex) { if (ErrorData.currentErrorType == ErrorData.ErrorType.ConnectionError) { @@ -262,23 +346,28 @@ private void execute(Action action) throws Exception { throw ex; } } - + break; case GOTO_FLOOR: try { if (GotoFloor.run()) { - Go.log(String.format("Goto: AP: %d/%d, BC: %d/%d, Front:%s>%s", - info.ap, info.apMax, info.bc, info.bcMax, - info.area.get(Integer.parseInt(info.front.areaId)).areaName, - info.front.floorId)); + Go.log(String.format( + "Goto: AP: %d/%d, BC: %d/%d, Front:%s > %s层", + info.ap, + info.apMax, + info.bc, + info.bcMax, + info.area.get(Integer.parseInt(info.front.areaId)).areaName, + info.front.floorId)); } else { - + } } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; - + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; + } - + break; case PRIVATE_FAIRY_BATTLE: try { @@ -287,14 +376,16 @@ private void execute(Action action) throws Exception { if (!info.events.empty()) { switch (info.events.peek()) { case fairyBattleEnd: - result = "Too Late"; + result = "Late"; info.events.pop(); break; case fairyBattleLose: + info.count2++; result = "Lose"; info.events.pop(); break; case fairyBattleWin: + info.count3++; result = "Win"; info.events.pop(); break; @@ -302,37 +393,52 @@ private void execute(Action action) throws Exception { break; } } - String str = String.format("PFB name=%s(%s), Lv: %s, HP: %d, MaxHP: %d, bc: %d/%d, ap: %d/%d, ticket: %d, %s", - info.fairy.FairyName, - info.FairySelectUserList.containsKey(info.fairy.UserId) ? info.FairySelectUserList.get(info.fairy.UserId).userName : "NA", - info.fairy.FairyLevel, - info.fairy.fairyCurrHp, - info.fairy.fairyMaxHp, - info.bc, - info.bcMax, - info.ap, - info.apMax, - info.ticket, result); - if (info.gather != -1) str += String.format(", gather=%d", info.gather); - Go.log(str); + String str1 = String + .format("妖精:%s(%s), Lv:%3s, HP:%6d/%6d", + info.fairy.FairyName, + info.FairySelectUserList + .containsKey(info.fairy.UserId) ? info.FairySelectUserList + .get(info.fairy.UserId).userName + : "NA", info.fairy.FairyLevel, + info.fairy.fairyCurrHp, + info.fairy.fairyMaxHp); + String str2 = String.format( + "状态:bc:%3d/%3d, ap:%3d/%3d, T:%2d, %s", info.bc, + info.bcMax, info.ap, info.apMax, info.ticket, + result); + Go.log(str1); + Go.log(str2); + if (info.gather != -1) { + String str3 = String.format("收集:%6d, 舔:%3d, 尾:%3d", + info.gather, info.count2, info.count3); + Go.log(str3); + } } else { - + } } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } + break; case EXPLORE: try { if (Explore.run()) { - Go.log(String.format("Explore[%s>%s]: AP: %d, Gold+%s=%d, Exp+%s, Progress:%s, Result: %s.", - info.area.get(Integer.parseInt(info.front.areaId)).areaName, info.front.floorId,info.ap, - info.ExploreGold, info.money, info.ExploreExp, info.ExploreProgress, info.ExploreResult)); + Go.log(String + .format("Explore[%s>%s层>%s]: AP: %d, Gold+%s=%d, Exp+%s, Progress:%s, Result: %s.", + info.area.get(Integer + .parseInt(info.front.areaId)).areaName, + info.front.floorId, info.front.cost, + info.ap, info.ExploreGold, info.money, + info.ExploreExp, info.ExploreProgress, + info.ExploreResult)); } else { - + } } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } break; case GUILD_BATTLE: @@ -342,7 +448,7 @@ private void execute(Action action) throws Exception { if (!info.events.empty()) { switch (info.events.peek()) { case guildTopRetry: - result = "Too Late"; + result = "Late"; break; case fairyBattleLose: result = "Lose"; @@ -356,27 +462,38 @@ private void execute(Action action) throws Exception { break; } } - String str = String.format("PFB name=%s, Lv: %s, HP: %d, MaxHP: %d, bc: %d/%d, ap: %d/%d, ticket: %d, week:%s, %s", - info.gfairy.FairyName, info.gfairy.FairyLevel, info.gfairy.fairyCurrHp, info.gfairy.fairyMaxHp, info.bc, info.bcMax, info.ap, info.apMax, - info.ticket, info.week, result); + String str1 = String.format("外敌:%s, Lv:%3s, HP:%8d/%8d", + info.gfairy.FairyName, info.gfairy.FairyLevel, + info.gfairy.fairyCurrHp, info.gfairy.fairyMaxHp); + String str2 = String.format( + "状态:bc:%3d/%3d, ap:%3d/%3d, Buff:%10s, %4s", + info.bc, info.bcMax, info.ap, info.apMax, + info.gfairy.Spp, result); + String str3 = String.format( + "贡献:%5s+%5s=%5s(%3s)week:%9s, T:%2d, exp:%5d", + info.gfairy.battle_contribution, + info.gfairy.hp_contribution, + info.gfairy.contribution, + info.gfairy.attack_compensation, info.week, + info.ticket, info.exp); Thread.sleep(5000); - Go.log(str); + Go.log(str1); + Go.log(str2); + Go.log(str3); } else { - + } } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } break; case GUILD_TOP: try { - if (GuildTop.run()) { - // nothing to do - } else { - if (info.NoFairy && Info.nightModeSwitch) Go.log("Night Mode"); - } + GuildTop.run(); } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } break; case GET_FAIRY_REWARD: @@ -384,21 +501,31 @@ private void execute(Action action) throws Exception { if (GetFairyReward.run()) { Go.log(ErrorData.text); ErrorData.clear(); + + if (Info.receiveBox == true) { + GetRewardBox.list(); + if (Process.info.boxList.size() >= 650) + GetRewardBox.get(); + + } } } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } break; case LV_UP: try { if (LvUp.run()) { - Go.log(String.format("Level UP! AP:%d BC:%d", Process.info.apMax, Process.info.bcMax)); + // Go.log(String.format("Level UP! AP:%d BC:%d", + // Process.info.apMax, Process.info.bcMax)); } } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } break; - + case SELL_CARD: try { if (SellCard.run()) { @@ -408,7 +535,8 @@ private void execute(Action action) throws Exception { Go.log("Something wrong"); } } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } break; case USE: @@ -416,14 +544,16 @@ private void execute(Action action) throws Exception { if (Use.run()) { Go.log(ErrorData.text); ErrorData.clear(); - Go.log(String.format("Bottles: FA:%d, HA:%d, HA(T):%d, FB:%d, HB:%d, HB(T):%d", - info.fullAp, info.halfAp, info.halfApToday, - info.fullBc, info.halfBc, info.halfBcToday)); + Go.log(String + .format("Bottles: FA:%d, HA:%d, HA(T):%d, FB:%d, HB:%d, HB(T):%d", + info.fullAp, info.halfAp, info.halfApToday, + info.fullBc, info.halfBc, info.halfBcToday)); } else { Go.log("Sth Wrong @USE"); } } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } break; case PFB_GOOD: @@ -435,8 +565,9 @@ private void execute(Action action) throws Exception { Go.log("Something wrong"); } } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; - + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; + } break; case RECV_PFB_GOOD: @@ -448,7 +579,8 @@ private void execute(Action action) throws Exception { Go.log("Something wrong"); } } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; + if (ErrorData.currentErrorType == ErrorData.ErrorType.none) + throw ex; } break; case NOTHING: @@ -456,14 +588,15 @@ private void execute(Action action) throws Exception { break; default: break; - + } } - + public static Document ParseXMLBytes1(byte[] in) throws Exception { ByteArrayInputStream bais = null; try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilderFactory factory = DocumentBuilderFactory + .newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); bais = new ByteArrayInputStream(in); Document document = builder.parse(bais); @@ -472,63 +605,67 @@ public static Document ParseXMLBytes1(byte[] in) throws Exception { throw e; } } - + public static Document ParseXMLBytes(byte[] in) throws Exception { ByteArrayInputStream bais = null; try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilderFactory factory = DocumentBuilderFactory + .newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); bais = new ByteArrayInputStream(in); Document document = builder.parse(bais); - if(Info.debug) doc2FormatString(document); //输出xml + if (Info.debug) + doc2FormatString(document); // 输出xml return document; } catch (Exception e) { throw e; } } - - public static void doc2FormatString(Document doc) { + + public static void doc2FormatString(Document doc) { String docString = ""; - if(doc != null){ + if (doc != null) { StringWriter stringWriter = new StringWriter(); - try{ - OutputFormat format = new OutputFormat(doc,"UTF-8",true); - //format.setIndenting(true);//设置是否缩进,默认为true - //format.setIndent(4);//设置缩进字符数 - //format.setPreserveSpace(false);//设置是否保持原来的格式,默认为 false - //format.setLineWidth(500);//设置行宽度 - XMLSerializer serializer = new XMLSerializer(stringWriter,format); + try { + OutputFormat format = new OutputFormat(doc, "UTF-8", true); + // format.setIndenting(true);//设置是否缩进,默认为true + // format.setIndent(4);//设置缩进字符数 + // format.setPreserveSpace(false);//设置是否保持原来的格式,默认为 false + // format.setLineWidth(500);//设置行宽度 + XMLSerializer serializer = new XMLSerializer(stringWriter, + format); serializer.asDOMSerializer(); serializer.serialize(doc); docString = stringWriter.toString(); - }catch(Exception e){ + } catch (Exception e) { e.printStackTrace(); - }finally{ - if(stringWriter != null){ - try { + } finally { + if (stringWriter != null) { + try { stringWriter.close(); } catch (IOException e) { e.printStackTrace(); } - } + } } } - File f=new File("xml/"); + File f = new File("xml/"); // 创建文件夹 - if (!f.exists()) { - f.mkdirs(); - } - - //System.out.println(docString); - File fp=new File(String.format("xml/%d.xml", System.currentTimeMillis())); - PrintWriter pfp; + if (!f.exists()) { + f.mkdirs(); + } + + // System.out.println(docString); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); + File fp = new File(String.format("xml/%s.xml", df.format(new Date()))); + PrintWriter pfp; try { pfp = new PrintWriter(fp); - pfp.print(docString); - pfp.close(); + pfp.print(docString); + pfp.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } - //return docString; + // return docString; } } diff --git a/walker/Think.java b/src/walker/Think.java similarity index 55% rename from walker/Think.java rename to src/walker/Think.java index 2bfc4bf..7cb85fb 100644 --- a/walker/Think.java +++ b/src/walker/Think.java @@ -1,6 +1,7 @@ package walker; import info.Card; +import info.FairyBattleInfo; import java.util.List; @@ -8,19 +9,21 @@ import action.ActionRegistry.Action; public class Think { - + private static final String AP_HALF = "101"; private static final String BC_HALF = "111"; private static final String AP_FULL = "1"; private static final String BC_FULL = "2"; - + private static final int EXPLORE_NORMAL = 60; private static final int EXPLORE_URGENT = 80; private static final int GFL_PRI = 50; private static final int GFL_HI_PRI = 70; private static final int GF_PRI = 25; private static final int USE_PRI = 99; - public static ActionRegistry.Action doIt (List possible) { + + public static ActionRegistry.Action doIt( + List possible) { Action best = Action.NOTHING; int score = Integer.MIN_VALUE + 20; for (int i = 0; i < possible.size(); i++) { @@ -51,11 +54,8 @@ public static ActionRegistry.Action doIt (List possible) } break; case PRIVATE_FAIRY_BATTLE: - if (Info.Profile == 2) { - Process.info.fairy.No = "2"; + if (Think.canBattle()) return Action.PRIVATE_FAIRY_BATTLE; - } - if (Think.canBattle()) return Action.PRIVATE_FAIRY_BATTLE; break; case EXPLORE: int p = explorePoint(); @@ -78,7 +78,9 @@ public static ActionRegistry.Action doIt (List possible) case NOTHING: break; case SELL_CARD: - if (cardsToSell()) return Action.SELL_CARD; + if (Info.autoSellCard == true && cardsToSell() == true) { + return Action.SELL_CARD; + } break; case LV_UP: decideUpPoint(); @@ -96,9 +98,9 @@ public static ActionRegistry.Action doIt (List possible) } return best; } - + private static int decideUse() { - + if (Info.autoUseAp) { if (Process.info.ap < Info.autoApLow) { switch (Info.autoApType) { @@ -127,7 +129,7 @@ private static int decideUse() { break; default: break; - + } } } @@ -159,7 +161,7 @@ private static int decideUse() { break; default: break; - + } } } @@ -169,133 +171,109 @@ private static int decideUse() { private static boolean canBattle() { switch (Process.info.fairy.Type) { case 0: - Process.info.gfairy.No = Info.PublicFairyBattle.No; break; - case 4: - if (Info.AllowBCInsuffient == false && Process.info.bc < Info.FriendFairyBattleNormal.BC) return false; - if (Process.info.bc < 2) return false; - Process.info.fairy.No = Info.FriendFairyBattleNormal.No; - break; - case 5: - if(Info.AllowBCInsuffient == false) { - if(Process.info.bc < Info.FriendFairyBattleRare.BC) { - return false; - } else { - Process.info.fairy.No = Info.FriendFairyBattleRare.No; - } - } else if(Process.info.bc >= 2) { - Process.info.fairy.No = Info.FriendFairyBattleRare.No; - } else { + case FairyBattleInfo.PRIVATE: + case FairyBattleInfo.PRIVATE | FairyBattleInfo.RARE: + if (Process.info.bc < Info.FriendFairyBattleNormal.BC + || Process.info.bc < 2) { return false; } + break; - case 6: - if (Info.AllowBCInsuffient == false && Process.info.bc < Info.PrivateFairyBattleNormal.BC) return false; - if (Process.info.bc < 2) return false; - Process.info.fairy.No = Info.PrivateFairyBattleNormal.No; - break; - case 7: - if(Info.AllowBCInsuffient == false) { - if(Process.info.bc < Info.PrivateFairyBattleRare.BC) { - return false; - } else { - Process.info.fairy.No = Info.PrivateFairyBattleRare.No; - } - } else if(Process.info.bc >= 2) { - Process.info.fairy.No = Info.PrivateFairyBattleRare.No; - } else { + case FairyBattleInfo.PRIVATE | FairyBattleInfo.SELF: + case FairyBattleInfo.PRIVATE | FairyBattleInfo.SELF + | FairyBattleInfo.RARE: + if (Process.info.bc < Info.PrivateFairyBattleNormal.BC + || Process.info.bc < 2) { return false; } + break; default: return false; } + return true; } - + private static void decideUpPoint() { - if (Info.Profile == 1) { - //主号全加BC + if (Info.AutoAddp == 1) { + // 主号全加BC Process.info.apUp = 0; Process.info.bcUp = Process.info.pointToAdd; - } else if (Info.Profile == 2) { - //小号全加AP + } else if (Info.AutoAddp == 2) { + // 小号全加AP Process.info.apUp = Process.info.pointToAdd; Process.info.bcUp = 0; } } - + private static int explorePoint() { try { - if (Info.Profile == 2) { - if (Process.info.ap < 1) return Integer.MIN_VALUE; - Process.info.front = Process.info.floor.get(1); - return EXPLORE_URGENT; - } - if (Process.info.bc == 0) return Integer.MIN_VALUE; - // 首先确定楼层 - if (Process.info.AllClear) { - int ap = Process.info.ap / Process.info.bc * Info.PrivateFairyBattleNormal.BC; - if (ap > 1) { - Process.info.front = Process.info.floor.get(ap); - } else { - Process.info.front = Process.info.floor.get(1); - } - } - if (Info.OneAPOnly) Process.info.front = Process.info.floor.get(1); // 判断是否可以行动 - if (Process.info.front == null) Process.info.front = Process.info.floor.get(1); - if (!Info.AllowBCInsuffient && Process.info.bc < Info.PrivateFairyBattleNormal.BC) return Integer.MIN_VALUE; - if (Process.info.ap < Process.info.front.cost) return Integer.MIN_VALUE; - if (Process.info.ap == Process.info.apMax) return EXPLORE_URGENT; + if (Process.info.front == null) + Process.info.front = Process.info.floor.firstEntry().getValue(); + if (!Info.AllowBCInsuffient + && Process.info.bc < Info.PrivateFairyBattleNormal.BC) + return Integer.MIN_VALUE; + if (Process.info.ap < Process.info.front.cost) + return Integer.MIN_VALUE; + if (Process.info.ap == Process.info.apMax) + return EXPLORE_URGENT; } catch (Exception ex) { ex.printStackTrace(); return Integer.MIN_VALUE; } return EXPLORE_NORMAL; } - private static boolean cardsToSell() { - if (Info.Profile == 2) { - int count = 0; - String toSell = ""; - for (Card c : Process.info.cardList) { - if (!Info.KeepCard.contains(c.serialId)) { - if (toSell.isEmpty()) { - toSell = c.serialId; - } else { - toSell += "," + c.serialId; - } - count++; - } - if (count >= 30) break; + + public static boolean cardsToSell() { + int count = 0; + String toSell = ""; + + for (Card c : Process.info.cardList) { + if (!c.exist) { + continue; } - Process.info.toSell = toSell; - return false; // 测试状态 - //return !toSell.isEmpty(); - } else if (Info.Profile == 1) { - int count = 0; - String toSell = ""; - for (Card c : Process.info.cardList) { - if (!c.exist) continue; - if (c.holo && c.hp >= 3500) continue; //闪卡不卖,但是低等级的闪卡照样要卖 - if (c.hp > 6000) continue; //防止不小心把贵重卡片卖了 - if (Info.CanBeSold.contains(c.cardId)) { - if (toSell.isEmpty()) { - toSell = c.serialId; - } else { - toSell += "," + c.serialId; - } - count++; - c.exist = false; + + // 闪卡不卖,但是低等级的闪卡照样要卖 + if (c.holo && c.price >= 3000) { + continue; + } + + // 防止不小心把贵重卡片卖了 + if (c.hp > 6000) { + continue; + } + + // 各种切利 + if (c.hp <= 2 && c.atk <= 2 && !Info.CanBeSold.contains(c.cardId)) { + continue; + } + + // 狼娘 牛仔 女仆 不卖(若用户不特别指定) + if ((c.cardId.equals(124) || c.cardId.equals(142) || c.cardId + .equals(9)) && !Info.CanBeSold.contains(c.cardId)) { + continue; + } + + if (c.price <= 3000 || Info.CanBeSold.contains(c.cardId)) { + if (toSell.isEmpty()) { + toSell = c.serialId; + } else { + toSell += "," + c.serialId; } - if (count >= 30) break; + count++; + c.exist = false; + } + + if (count >= 30) { + break; } - - Process.info.toSell = toSell; - return !toSell.isEmpty(); } - return false; - + + Process.info.toSell = toSell; + return !toSell.isEmpty(); } - + } diff --git a/src/walker/Version.java b/src/walker/Version.java new file mode 100644 index 0000000..d13c93c --- /dev/null +++ b/src/walker/Version.java @@ -0,0 +1,21 @@ +package walker; + +public class Version { + private static String major = "2"; + private static String minor = "5"; + private static String release = "0"; + private static String thanks = "@wjsjwr, @tsubasa617, @AsakuraFuuko, @lucky83, @innocentius, @kimbaol, @djj200504001"; + + public static String strVersion() { + return String.format("MAWalker(java) v%s.%s.%s", major, minor, release); + + } + + public static String strThanks() { + return String.format("对下列网友表示感谢(排名不分先后): %s", thanks); + } + + public static String strInfo() { + return "本软件为免费开源软件,不收取任何费用。\n最新版本及提交bug,请到https://github.com/tsubasa617/MAWalker"; + } +} diff --git a/walker/ErrorData.java b/walker/ErrorData.java deleted file mode 100644 index de155ee..0000000 --- a/walker/ErrorData.java +++ /dev/null @@ -1,89 +0,0 @@ -package walker; - -/** - * 处理内部错误,在execute时,如果是run所捕获的错误,则放入此类中。 - * 这样,当execute捕获到错误时,首先检查此类中有无存放错误信息, - * 如果有,则转入错误信息处理; - * 如果没有,则说明是其他位置的异常,另行处理。 - */ -public class ErrorData { - - public enum DataType { - bytes, - text, - none - } - public static DataType currentDataType = DataType.none; - public static ErrorType currentErrorType = ErrorType.none; - public static byte[] bytes; - public static String text; - - public enum ErrorType { - // 总体 - none, - ConnectionError, - // 登录 - LoginDataError, - LoginDataParseError, - LoginResponse, - // 获取地图 - AreaDataError, - AreaDataParseError, - AreaResponse, - // 上街 - GotoFloorDataError, - GotoFloorDataParseError, - GotoFloorResponse, - // 获取妖精列表 - FairyListDataError, - FairyListDataParseError, - FairyListResponse, - // 妖精战斗 - PrivateFairyBattleDataError, - PrivateFairyBattleDataParseError, - PrivateFairyBattleResponse, - //探索 - ExploreDataError, - ExploreDataParseError, - ExploreResponse, - // 外敌界面 - GuildTopDataError, - GuildTopDataParseError, - GuildTopResponse, - // 外敌战 - GuildBattleDataError, - GuildBattleDataParseError, - GuildBattleResponse, - // 获取妖精站礼物 - GetFairyRewardDataError, - GetFairyRewardResponse, - // 卖卡 - SellCardDataError, - SellCardResponse, - // 升级 - LvUpDataError, - LvUpResponse, - // 赞 - PFB_GoodDataError, - PFB_GoodResponse, - // fairy_history - FairyHistoryDataError, - FairyHistoryDataParseError, - FairyHistoryResponse, - // 收赞 - RecvPFBGoodDataError, - RecvPFBGoodDataParseError, - RecvPFBGoodResponse, - // 吃药 - UseDataError, - UseResponse - } - - - public static void clear() { - bytes = null; - text = null; - currentDataType = DataType.none; - currentErrorType = ErrorType.none; - } -} diff --git a/walker/GetConfig.java b/walker/GetConfig.java deleted file mode 100644 index f2a9f28..0000000 --- a/walker/GetConfig.java +++ /dev/null @@ -1,126 +0,0 @@ -package walker; - -import java.util.ArrayList; - -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathFactory; - -import net.Network; - -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class GetConfig { - public static void parse(Document doc) throws Exception { - try { - XPathFactory factory = XPathFactory.newInstance(); - XPath xpath = factory.newXPath(); - - Info.LoginId = xpath.evaluate("/config/username", doc); - Info.LoginPw = xpath.evaluate("/config/password", doc); - Network.UserAgent = xpath.evaluate("/config/user_agent", doc); - - Info.Profile = Integer.parseInt(xpath.evaluate("/config/profile", doc)); - - switch (Info.Profile) { - case 1: - NodeList idl = (NodeList)xpath.evaluate("/config/sell_card/id", doc, XPathConstants.NODESET); - Info.CanBeSold = new ArrayList(); - for (int i = 0; i< idl.getLength(); i++) { - Node idx = idl.item(i); - try { - Info.CanBeSold.add(idx.getFirstChild().getNodeValue()); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - Info.FairyBattleFirst = xpath.evaluate("/config/option/fairy_battle_first", doc).equals("1"); - Info.AllowBCInsuffient = xpath.evaluate("/config/option/allow_bc_insuffient", doc).equals("1"); - Info.OneAPOnly = xpath.evaluate("/config/option/one_ap_only", doc).equals("1"); - Info.AutoAddp = xpath.evaluate("/config/option/auto_add_point", doc).equals("1"); - Info.AllowAttackSameFairy = xpath.evaluate("/config/option/allow_attack_same_fairy", doc).equals("1"); - Info.debug = xpath.evaluate("/config/option/debug", doc).equals("1"); - Info.nightModeSwitch = xpath.evaluate("/config/option/night_mode", doc).equals("1"); - Info.receiveBattlePresent = xpath.evaluate("/config/option/receive_battle_present", doc).equals("1"); - - Info.autoUseAp = xpath.evaluate("/config/use/auto_use_ap", doc).equals("1"); - if (Info.autoUseAp) { - String half = xpath.evaluate("/config/use/strategy/ap/half", doc); - if (half.equals("0")) { - Info.autoApType = Info.autoUseType.FULL_ONLY; - } else if (half.equals("1")) { - Info.autoApType = Info.autoUseType.HALF_ONLY; - } else { - Info.autoApType = Info.autoUseType.ALL; - } - Info.autoApLow = Integer.parseInt(xpath.evaluate("/config/use/strategy/ap/low",doc)); - Info.autoApFullLow = Integer.parseInt(xpath.evaluate("/config/use/strategy/ap/full_low",doc)); - } - Info.autoUseBc = xpath.evaluate("/config/use/auto_use_bc", doc).equals("1"); - if (Info.autoUseBc) { - String half = xpath.evaluate("/config/use/strategy/bc/half", doc); - if (half.equals("0")) { - Info.autoBcType = Info.autoUseType.FULL_ONLY; - } else if (half.equals("1")) { - Info.autoBcType = Info.autoUseType.HALF_ONLY; - } else { - Info.autoBcType = Info.autoUseType.ALL; - } - Info.autoBcLow = Integer.parseInt(xpath.evaluate("/config/use/strategy/bc/low",doc)); - Info.autoBcFullLow = Integer.parseInt(xpath.evaluate("/config/use/strategy/bc/full_low",doc)); - } - - - - - - - Info.FriendFairyBattleRare.No = xpath.evaluate("/config/deck/deck_profile[name='FriendFairyBattleRare']/no", doc); - Info.FriendFairyBattleRare.BC = Integer.parseInt(xpath.evaluate("/config/deck/deck_profile[name='FriendFairyBattleRare']/bc", doc)); - - Info.FriendFairyBattleNormal.No = xpath.evaluate("/config/deck/deck_profile[name='FriendFairyBattleNormal']/no", doc); - Info.FriendFairyBattleNormal.BC = Integer.parseInt(xpath.evaluate("/config/deck/deck_profile[name='FriendFairyBattleNormal']/bc", doc)); - - Info.PublicFairyBattle.BC = Integer.parseInt(xpath.evaluate("/config/deck/deck_profile[name='GuildFairyDeck']/bc", doc)); - Info.PublicFairyBattle.No = xpath.evaluate("/config/deck/deck_profile[name='GuildFairyDeck']/no", doc); - - Info.PrivateFairyBattleNormal.No = xpath.evaluate("/config/deck/deck_profile[name='FairyDeck']/no", doc); - Info.PrivateFairyBattleNormal.BC = Integer.parseInt(xpath.evaluate("/config/deck/deck_profile[name='FairyDeck']/bc", doc)); - - Info.PrivateFairyBattleRare.No = xpath.evaluate("/config/deck/deck_profile[name='RareFairyDeck']/no", doc); - Info.PrivateFairyBattleRare.BC = Integer.parseInt(xpath.evaluate("/config/deck/deck_profile[name='RareFairyDeck']/bc", doc)); - - - break; - case 2: - - Info.OneAPOnly = true; - Info.AllowBCInsuffient = true; - Info.FairyBattleFirst = false; - - Info.FriendFairyBattleRare.No = "0"; - Info.FriendFairyBattleRare.BC = 0; - - Info.PublicFairyBattle.BC = 0; - Info.PublicFairyBattle.No = "0"; - - Info.PrivateFairyBattleNormal.No = "1"; - Info.PrivateFairyBattleNormal.BC = 97; - - Info.PrivateFairyBattleRare.No = "2"; - Info.PrivateFairyBattleRare.BC = 2; - - break; - } - - - } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) { - throw ex; - } - } - - } -} diff --git a/walker/Profile2.java b/walker/Profile2.java deleted file mode 100644 index e033898..0000000 --- a/walker/Profile2.java +++ /dev/null @@ -1,272 +0,0 @@ -package walker; - -import java.util.ArrayList; -import java.util.List; - -import walker.Info.TimeoutEntry; -import action.ActionRegistry; -import action.Explore; -import action.GetFloorInfo; -import action.GotoFloor; -import action.Login; -import action.LvUp; -import action.PFBGood; -import action.PrivateFairyBattle; -import action.RecvPFBGood; -import action.SellCard; -import action.ActionRegistry.Action; - -public class Profile2 { - - public Profile2() { - } - - public void auto() throws Exception { - try { - if (ErrorData.currentErrorType != ErrorData.ErrorType.none) { - rescue(); - } else { - long start = System.currentTimeMillis(); - execute(Think.doIt(getPossibleAction())); - long delta = System.currentTimeMillis() - start; - if (delta < 15000) Thread.sleep(15000 - delta); - } - } catch (Exception ex) { - throw ex; - } - } - - private void rescue() { - Go.log(ErrorData.currentErrorType.toString()); - switch (ErrorData.currentDataType) { - case bytes: - Go.log(new String(ErrorData.bytes)); - break; - case text: - Go.log(new String(ErrorData.text)); - break; - default: - break; - } - ErrorData.clear(); - } - - private List getPossibleAction() { - ArrayList result = new ArrayList(); - if (Process.info.events.size() != 0) { - switch(Process.info.events.peek()) { - case notLoggedIn: - case cookieOutOfDate: - result.add(ActionRegistry.Action.LOGIN); - break; - case fairyTransform: - Go.log("Rare Fairy Appear"); - case privateFairyAppear: - case fairyCanBattle: - result.add(ActionRegistry.Action.PRIVATE_FAIRY_BATTLE); - break; - case innerMapJump: - Go.log("Map Status Changed!"); - case needFloorInfo: - result.add(ActionRegistry.Action.GET_FLOOR_INFO); - break; - case cardFull: - result.add(ActionRegistry.Action.SELL_CARD); - break; - case needAPBCInfo: - result.add(ActionRegistry.Action.GOTO_FLOOR); - break; - case fairyReward: - result.add(ActionRegistry.Action.GET_FAIRY_REWARD); - break; - case levelUp: - result.add(Action.LV_UP); - break; - case PFBGood: - result.add(Action.PFB_GOOD); - break; - case recvPFBGood: - result.add(Action.RECV_PFB_GOOD); - break; - case gotoFloor: - result.add(Action.GOTO_FLOOR); - default: - Go.log("Profile2 Ignore: " + Process.info.events.peek()); - break; - } - Process.info.events.pop(); - return result; - } - ArrayList te = Process.info.CheckTimeout(); - for (TimeoutEntry e : te) { - switch (e) { - case apbc: - Process.info.events.push(Info.EventType.needAPBCInfo); - break; - case login: - Process.info.events.push(Info.EventType.cookieOutOfDate); - break; - case map: - Process.info.events.push(Info.EventType.needFloorInfo); - break; - case fairy: - case reward: - default: - break; - } - } - result.add(ActionRegistry.Action.EXPLORE); - return result; - } - - private void execute(ActionRegistry.Action action) throws Exception { - switch (action) { - case LOGIN: - try { - if (Login.run()) { - Go.log(String.format("User: %s, AP: %d/%d, BC: %d/%d, Card: %d/%d, ticket: %d", - Process.info.username, Process.info.ap, Process.info.apMax, Process.info.bc, Process.info.bcMax, - Process.info.cardList.size(), Process.info.cardMax, Process.info.ticket)); - Process.info.events.push(Info.EventType.needFloorInfo); - } else { - Process.info.events.push(Info.EventType.notLoggedIn); - } - } catch (Exception ex) { - Process.info.events.push(Info.EventType.notLoggedIn); - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) { - throw ex; - } - } - break; - case GET_FLOOR_INFO: - try { - if (GetFloorInfo.run()) { - Go.log(String.format("Area(%d) Front: %s>%s@c=%d", - Process.info.area.size(), - Process.info.area.get(Integer.parseInt(Process.info.front.areaId)).areaName, - Process.info.front.floorId, - Process.info.front.cost)); - } - - } catch (Exception ex) { - if (ex.getMessage().equals("302")) { - Process.info.events.push(Info.EventType.innerMapJump); - ErrorData.clear(); - } else { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; - } - } - break; - case GOTO_FLOOR: - try { - if (GotoFloor.run()) { - Go.log(String.format("Goto: AP: %d/%d, BC: %d/%d, Front:%s>%s", - Process.info.ap, Process.info.apMax, Process.info.bc, Process.info.bcMax, - Process.info.area.get(Integer.parseInt(Process.info.front.areaId)).areaName, - Process.info.front.floorId)); - } else { - - } - } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; - } - - break; - case PRIVATE_FAIRY_BATTLE: - try { - if (PrivateFairyBattle.run()) { - String result = ""; - if (!Process.info.events.empty()) { - switch (Process.info.events.peek()) { - case fairyBattleEnd: - result = "Too Late"; - Process.info.events.pop(); - break; - case fairyBattleLose: - result = "Lose"; - Process.info.events.pop(); - break; - case fairyBattleWin: - result = "Win"; - Process.info.events.pop(); - break; - default: - break; - } - } - String str = String.format("PFB name=%s, Lv: %s, bc: %d/%d, ap: %d/%d, ticket: %d, %s", - Process.info.fairy.FairyName, Process.info.fairy.FairyLevel, Process.info.bc, Process.info.bcMax, Process.info.ap, Process.info.apMax, - Process.info.ticket, result); - if (Process.info.gather != -1) str += String.format(", gather=%d", Process.info.gather); - Go.log(str); - } else { - - } - } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; - } - break; - case EXPLORE: - try { - if (Explore.run()) { - Go.log(String.format("Explore: AP: %d, Gold+%s, Exp+%s, Progress:%s, Result: %s.", Process.info.ap, - Process.info.ExploreGold, Process.info.ExploreExp, Process.info.ExploreProgress, Process.info.ExploreResult)); - } else { - - } - } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; - } - break; - case LV_UP: - try { - if (LvUp.run()) { - Go.log(String.format("Level UP! AP:%d BC:%d", Process.info.apMax, Process.info.bcMax)); - } - } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; - } - break; - case SELL_CARD: - try { - if (SellCard.run()) { - Go.log(ErrorData.text); - ErrorData.clear(); - } else { - Go.log("Something wrong"); - } - } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; - } - break; - case PFB_GOOD: - try { - if (PFBGood.run()) { - Go.log(ErrorData.text); - ErrorData.clear(); - } else { - Go.log("Something wrong"); - } - } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; - - } - break; - case RECV_PFB_GOOD: - try { - if (RecvPFBGood.run()) { - Go.log(ErrorData.text); - ErrorData.clear(); - } else { - Go.log("Something wrong"); - } - } catch (Exception ex) { - if (ErrorData.currentErrorType == ErrorData.ErrorType.none) throw ex; - } - break; - default: - break; - } - } - -} diff --git a/walker/Version.java b/walker/Version.java deleted file mode 100644 index 5f170fb..0000000 --- a/walker/Version.java +++ /dev/null @@ -1,19 +0,0 @@ -package walker; - -public class Version { - private static String major = "1"; - private static String minor = "0"; - private static String release = "36"; - private static String copyright = "2013©wjsjwr.org"; - private static String code = "Waive"; - private static String thanks = "@innocentius, @AsakuraFuuko"; - - public static String strVersion() { - return String.format("MAWalker(java) v%s.%s.%s %s, %s", major, minor, release, code, copyright); - } - - public static String strThanks(){ - return String.format("对下列网友表示感谢(排名不分先后): %s", thanks); - } - -}