├── .gitignore
├── src
├── META-INF
│ └── MANIFEST.MF
├── util
│ ├── regexUtil
│ │ ├── UnicodeUtil.java
│ │ └── RegexUtil.java
│ ├── netUtil
│ │ ├── ReLocateUtil.java
│ │ ├── ParametersBuilder.java
│ │ ├── PropertyBuilder.java
│ │ └── NetUtil.java
│ └── TimeUtil.java
├── main.fxml
└── Main.java
├── release
└── NetRobot.jar
├── screenshot
└── netrobot.png
├── .idea
├── encodings.xml
├── vcs.xml
├── description.html
├── modules.xml
├── artifacts
│ └── NetRobot_jar.xml
├── misc.xml
├── compiler.xml
└── uiDesigner.xml
├── NetRobot.iml
└── readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | src/main.java
2 |
--------------------------------------------------------------------------------
/src/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: Main
3 |
4 |
--------------------------------------------------------------------------------
/release/NetRobot.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/NetRobot/HEAD/release/NetRobot.jar
--------------------------------------------------------------------------------
/screenshot/netrobot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zzzia/NetRobot/HEAD/screenshot/netrobot.png
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/description.html:
--------------------------------------------------------------------------------
1 | Simple JavaFX 2.0 application that includes simple .fxml file with attached controller and Main class to quick start. Artifact to build JavaFX application is provided.
2 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/artifacts/NetRobot_jar.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | $PROJECT_DIR$/out/artifacts/NetRobot_jar
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NetRobot.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/util/regexUtil/UnicodeUtil.java:
--------------------------------------------------------------------------------
1 | package util.regexUtil;
2 |
3 | import java.util.regex.Matcher;
4 | import java.util.regex.Pattern;
5 |
6 | public class UnicodeUtil {
7 |
8 | public static String unicodeToString(String str) {
9 |
10 | Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
11 | Matcher matcher = pattern.matcher(str);
12 | char ch;
13 | while (matcher.find()) {
14 | ch = (char) Integer.parseInt(matcher.group(2), 16);
15 | str = str.replace(matcher.group(1), ch + "");
16 | }
17 | return str;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/util/netUtil/ReLocateUtil.java:
--------------------------------------------------------------------------------
1 | package util.netUtil;
2 |
3 | import java.io.IOException;
4 | import java.net.HttpURLConnection;
5 | import java.net.URL;
6 |
7 | public class ReLocateUtil {
8 |
9 | public static String getLocate(String url) throws IOException {
10 | URL u = new URL(url);
11 | HttpURLConnection conn = (HttpURLConnection) u.openConnection();
12 | String location = conn.getHeaderField("Location");
13 | conn.disconnect();
14 | if (location == null) {
15 | return url;
16 | } else {
17 | return location;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/util/TimeUtil.java:
--------------------------------------------------------------------------------
1 | package util;
2 |
3 | import java.util.Calendar;
4 | import java.util.Date;
5 |
6 | public class TimeUtil {
7 | public static Date getDate(int hour, int minute) {
8 | Calendar calendar = Calendar.getInstance();
9 | calendar.set(Calendar.HOUR_OF_DAY, hour);
10 | calendar.set(Calendar.MINUTE, minute - 1);
11 | calendar.set(Calendar.SECOND, 59);
12 | if (calendar.getTime().compareTo(new Date(System.currentTimeMillis())) > 0) {
13 | System.out.println("calendar.getTime().compareTo(new Date(System.currentTimeMillis())) > 0");
14 | return calendar.getTime();
15 | } else {
16 | calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) + 1);
17 | System.out.println(calendar.getTime());
18 | return calendar.getTime();
19 | }
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # NetRobot
2 |
3 | 一个抢课,抢票,抢Q币,抢优惠券的小软件,已实测多次,稳定快速,再没人抢的过你
4 |
5 | 原理:自定义header和formData模拟get/post请求,加入定时、轮训机制。
6 |
7 | 可设置定时,间隔,字符过滤等功能
8 |
9 | 使用方式:[简书](https://www.jianshu.com/p/465d7c5f73c8)
10 |
11 | 利益关系,使用服务器控制软件使用权,某些代码不开源
12 |
13 | 软件需要java环境,jar见out文件夹或者release
14 |
15 |
16 |
17 | ------
18 |
19 | ##### 一些设定:
20 |
21 | - 测试按钮用来发送一次请求,用于测试。开始按钮按下如果不设置持续时长后将会不停的发送请求。
22 |
23 | - 时间间隔50ms比较合适,若要减少,请小幅度更改。
24 |
25 | - 字符匹配可以匹配一个很长字符串中的某一部分,假设原始返回格式如下:
26 |
27 | ```json
28 | {
29 | "status": 200,
30 | "info": "ok",
31 | "message": "操作成功"
32 | }
33 | ```
34 |
35 | 当你填写 【"info": " 】-【 ",】,之后每次返回的状态就只会含ok字符了
36 |
37 | - 定时设置为24小时制,如果现在是19:00,你可以设置1:00表示定时到明天1点。
38 |
39 | 操作会提前1秒开始,不需要担心。
40 |
41 | 请确保矫正为网络时间。
42 |
43 | - 设置定时后可以设置持续时长,默认持续3秒(已经很多了,假设间隔50ms,3秒能发送60次请求,设置3秒是怕时间和服务器时间有误差)
44 |
45 | - 最后希望觉得有帮助的朋友给一个star
--------------------------------------------------------------------------------
/src/util/netUtil/ParametersBuilder.java:
--------------------------------------------------------------------------------
1 | package util.netUtil;
2 |
3 | public class ParametersBuilder {
4 | private StringBuilder parameters = new StringBuilder();
5 | private boolean isJson = true;
6 |
7 | public ParametersBuilder putJson(String key, String value) {
8 | isJson = true;
9 | parameters.append(key);
10 | parameters.append("=");
11 | parameters.append(value);
12 | parameters.append("&");
13 | return this;
14 | }
15 |
16 | public ParametersBuilder put(String str) {
17 | isJson = false;
18 | parameters.append(str);
19 | return this;
20 | }
21 |
22 | public String getParameters() {
23 | if (isJson) {
24 | int lastPosition = parameters.length();
25 | parameters.delete(lastPosition - 1, lastPosition);
26 | return parameters.toString();
27 | } else return parameters.toString();
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | return getParameters();
33 | }
34 | }
--------------------------------------------------------------------------------
/src/util/netUtil/PropertyBuilder.java:
--------------------------------------------------------------------------------
1 | package util.netUtil;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | public class PropertyBuilder {
7 |
8 | private final Map properties = getDefaultProperty();
9 |
10 | public PropertyBuilder addProperty(String key, String value) {
11 | properties.put(key, value);
12 | return this;
13 | }
14 |
15 | public PropertyBuilder addProperty(Map properties) {
16 | this.properties.putAll(properties);
17 | return this;
18 | }
19 |
20 | public Map getProperty() {
21 | return properties;
22 | }
23 |
24 | private Map getDefaultProperty() {
25 | Map propertys = new HashMap<>();
26 | propertys.put("accept", "*/*");
27 | propertys.put("connection", "Keep-Alive");
28 | propertys.put("Charsert", "UTF-8");
29 | propertys.put("user-agent",
30 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
31 | propertys.put("Content-Type", "application/x-www-form-urlencoded");
32 | return propertys;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/util/regexUtil/RegexUtil.java:
--------------------------------------------------------------------------------
1 | package util.regexUtil;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 | import java.net.URL;
7 | import java.net.URLConnection;
8 | import java.util.ArrayList;
9 | import java.util.List;
10 | import java.util.regex.Matcher;
11 | import java.util.regex.Pattern;
12 |
13 | public class RegexUtil {
14 |
15 | private final static int TYPE_INCLUDE = 1;
16 | private final static int TYPE_EXCEPT = 2;
17 | public static boolean openLog = false;
18 |
19 | //包含正则表达式
20 | private static String Include(String start, String end) {
21 | return start + "[\\s\\S]*?" + end;
22 | }
23 |
24 | //不包含正则表达式
25 | private static String Except(String start, String end) {
26 | return "(?<=" + start + ")[\\s\\S]*?(?=" + end + ")";
27 | }
28 |
29 | //解析逻辑
30 | private static List regex(String start, String end, String source, int type) {
31 | List list = new ArrayList<>();
32 | String regEx;
33 | //设置解析方式
34 | if (type == TYPE_EXCEPT) {
35 | regEx = Except(start, end);
36 | } else regEx = Include(start, end);
37 | Pattern pattern = Pattern.compile(regEx);
38 | //将目标集合里的所有内容解析出来,放到这里的list里
39 | Matcher matcher = pattern.matcher(source);
40 | while (matcher.find()) {
41 | if (matcher.group() != null) {
42 | list.add(matcher.group());
43 | }
44 | }
45 | return list;
46 | }
47 |
48 | public static List regexInclude(String start, String end, String source) {
49 | if (source == null || source.length() == 0) return new ArrayList<>();
50 | return regex(start, end, source, TYPE_INCLUDE);
51 | }
52 |
53 | public static List regexExcept(String start, String end, String source) {
54 | if (source == null || source.length() == 0) return new ArrayList<>();
55 | return regex(start, end, source, TYPE_EXCEPT);
56 | }
57 |
58 | public static List getTags(String tagName, String source) {
59 | Matcher matcher = Pattern
60 | .compile("<" + tagName + ".*?>[\\s\\S]*?" + tagName + ">|<" + tagName + "[\\s\\S]*?>")
61 | .matcher(source);
62 | List list = new ArrayList<>();
63 | while (matcher.find()) {
64 | list.add(new Tag(matcher.group()));
65 | }
66 | return list;
67 | }
68 |
69 |
70 | /**
71 | * 同步获取html文件,默认编码utf-8
72 | *
73 | * @param url
74 | * @return
75 | */
76 | public static String getHtml(String url) throws IOException {
77 | return getHtml(url, "utf-8");
78 | }
79 |
80 | public static String getHtml(String url, String encodeType) throws IOException {
81 | if (openLog) System.out.println("connect : " + url);
82 | StringBuilder result = new StringBuilder();
83 | BufferedReader in = null;
84 | URL realUrl = new URL(url);
85 | // 打开和URL之间的连接
86 | URLConnection connection = realUrl.openConnection();
87 | // 设置通用的请求属性
88 | connection.setConnectTimeout(5000);
89 | connection.setReadTimeout(5000);
90 | connection.setRequestProperty("accept", "*/*");
91 | connection.setRequestProperty("connection", "Keep-Alive");
92 | connection.setRequestProperty("Charsert", "UTF-8");
93 | connection.setRequestProperty("user-agent",
94 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
95 | // 建立实际的连接
96 | connection.connect();
97 | // 定义 BufferedReader输入流来读取URL的响应
98 | in = new BufferedReader(new InputStreamReader(connection.getInputStream(), encodeType));
99 | String line;
100 | while ((line = in.readLine()) != null) {
101 | result.append(line);
102 | }
103 | in.close();
104 | if (openLog) System.out.println(result);
105 | return result.toString();
106 | }
107 |
108 | /**
109 | * 用于解析类似..的工具
110 | */
111 | public static class Tag {
112 | private String tagName;
113 | private String text;
114 | private String html;
115 | private String prefix;//前缀
116 | private String suffix;//后缀
117 |
118 | @Override
119 | public String toString() {
120 | return "html: " + getHtml() + "\n"
121 | + "tagName: " + getTagName() + "\n"
122 | + "text: " + getText() + "\n"
123 | + "prefix: " + getPrefix() + "\n"
124 | + "suffix: " + getSuffix() + "\n";
125 | }
126 |
127 | public Tag(String html) {
128 | this.html = html;
129 | }
130 |
131 | public String getTagName() {
132 | if (tagName == null)
133 | setTagName();
134 | return tagName;
135 | }
136 |
137 | private void setTagName() {
138 | Matcher matcher = Pattern.compile("<.*?/(.*?)>").matcher(getSuffix());
139 | if (matcher.find())
140 | tagName = matcher.group(1);
141 | if (tagName == null) tagName = "";
142 | }
143 |
144 | public String getText() {
145 | if (text == null)
146 | setText();
147 | return text;
148 | }
149 |
150 | private void setText() {
151 | Matcher matcher = Pattern.compile("<.*?>([\\s\\S]*)<.*?>").matcher(getHtml());
152 | if (matcher.find())
153 | text = matcher.group(1);
154 | if (text == null) text = "";
155 | }
156 |
157 | public String getHtml() {
158 | return html;
159 | }
160 |
161 | public String getPrefix() {
162 | if (prefix == null)
163 | setSPfix();
164 | return prefix;
165 | }
166 |
167 | //设置前后缀
168 | private void setSPfix() {
169 | Matcher matcher = Pattern.compile("<.*?>").matcher(html);
170 | if (matcher.find()) {
171 | prefix = matcher.group();
172 | }
173 | while (matcher.find()) {
174 | suffix = matcher.group();
175 | }
176 |
177 | if (prefix == null) prefix = "";
178 | if (suffix == null) suffix = "";
179 | }
180 |
181 | public String getSuffix() {
182 | if (suffix == null)
183 | setSPfix();
184 | return suffix;
185 | }
186 |
187 | //通过关键字获取属性
188 | public String getValue(String key) {
189 | Matcher matcher = Pattern.compile(key + "='(.*?)'|" + key + "=\"(.*?)\"").matcher(getPrefix());
190 | while (matcher.find()) {
191 | if (matcher.group(1) != null)
192 | return matcher.group(1);
193 | if (matcher.group(2) != null)
194 | return matcher.group(2);
195 | }
196 | return "";
197 | }
198 | }
199 |
200 | }
201 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/src/util/netUtil/NetUtil.java:
--------------------------------------------------------------------------------
1 | package util.netUtil;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 | import java.io.OutputStream;
7 | import java.net.HttpURLConnection;
8 | import java.net.URL;
9 | import java.util.Map;
10 | import java.util.concurrent.ExecutorService;
11 | import java.util.concurrent.Executors;
12 | import java.util.concurrent.ScheduledThreadPoolExecutor;
13 | import java.util.concurrent.TimeUnit;
14 |
15 | public class NetUtil {
16 |
17 | private String url = "";
18 | private String encodeType = "utf-8";
19 | private boolean doGet = true;
20 | private boolean openLog = true;
21 | private boolean reLocation = false;
22 | private int maxThreadCount = 10;
23 | private ParametersBuilder parametersBuilder = null;
24 | private PropertyBuilder propertyBuilder = new PropertyBuilder();
25 | private int connectTimeout = 5000;
26 | private int readTimeout = 5000;
27 | private ConnectFinishListener connectFinishListener = null;
28 | private ExecutorService executor;
29 | private ScheduledThreadPoolExecutor scheduled;
30 |
31 | private NetUtil(Builder builder) {
32 | url = builder.url;
33 | encodeType = builder.encodeType;
34 | doGet = builder.doGet;
35 | openLog = builder.openLog;
36 | parametersBuilder = builder.parametersBuilder;
37 | propertyBuilder = builder.propertyBuilder;
38 | connectTimeout = builder.connectTimeout;
39 | readTimeout = builder.readTimeout;
40 | reLocation = builder.reLocation;
41 | maxThreadCount = builder.maxThreadCount;
42 | connectFinishListener = builder.connectFinishListener;
43 | }
44 |
45 | public NetUtil(String url) {
46 | this.url = url;
47 | }
48 |
49 | public void stop() {
50 | if (executor != null) {
51 | executor.shutdownNow();
52 | executor = null;
53 | }
54 | if (scheduled != null) {
55 | scheduled.shutdownNow();
56 | scheduled = null;
57 | }
58 | }
59 |
60 | /**
61 | * 连接N次
62 | *
63 | * @param count 连接的次数
64 | */
65 | public void connect(int count) {
66 | executor = Executors.newFixedThreadPool(maxThreadCount);
67 | for (int i = 0; i < count; i++) {
68 | executor.execute(getRunnable());
69 | }
70 | }
71 |
72 | /**
73 | * 无限连接
74 | *
75 | * @param period 间隔时间
76 | */
77 | public void fuckingConnect(long period) {
78 | scheduled = new ScheduledThreadPoolExecutor(2);
79 | scheduled.scheduleAtFixedRate(getRunnable(), 0, period, TimeUnit.MILLISECONDS);
80 | }
81 |
82 | public Runnable getRunnable() {
83 | return () -> {
84 | try {
85 | connect();
86 | } catch (IOException e) {
87 | e.printStackTrace();
88 | }
89 | };
90 | }
91 |
92 | /**
93 | * 普通连接
94 | *
95 | * @return String
96 | * @throws IOException
97 | */
98 | public String connect() throws IOException {
99 | if (reLocation) {
100 | url = ReLocateUtil.getLocate(url);
101 | }
102 | if (openLog) System.out.println("connect : " + url);
103 | if (openLog && !doGet) System.out.println("parameters : " + parametersBuilder);
104 | StringBuilder result = new StringBuilder();
105 | BufferedReader in = null;
106 | URL realUrl = new URL(url);
107 | // 打开和URL之间的连接
108 | HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
109 | connection.setDoInput(true);
110 | connection.setRequestMethod("GET");
111 | connection.setConnectTimeout(connectTimeout);
112 | connection.setReadTimeout(readTimeout);
113 | // 设置请求头
114 | for (Map.Entry entry : propertyBuilder.getProperty().entrySet()) {
115 | connection.setRequestProperty(entry.getKey(), entry.getValue());
116 | }
117 | // 处理post请求
118 | if (!doGet) {
119 | connection.setRequestMethod("POST");
120 | }
121 | if (parametersBuilder != null) {
122 | connection.setDoOutput(true);
123 | OutputStream outputStream = connection.getOutputStream();
124 | outputStream.write(parametersBuilder.getParameters().getBytes());
125 | outputStream.flush();
126 | outputStream.close();
127 | }
128 | // 建立实际的连接
129 | connection.connect();
130 | // 定义 BufferedReader输入流来读取URL的响应
131 | in = new BufferedReader(new InputStreamReader(connection.getInputStream(), encodeType));
132 | String line;
133 | while ((line = in.readLine()) != null) {
134 | result.append(line);
135 | }
136 | in.close();
137 | connection.disconnect();
138 | String rs = result.toString();
139 | if (openLog) System.out.println(rs);
140 | if (connectFinishListener != null) connectFinishListener.onFinish(rs);
141 | return rs;
142 | }
143 |
144 | public static class Builder {
145 | private String url = "";
146 | private String encodeType = "utf-8";
147 | private int maxThreadCount = 10;
148 | private boolean reLocation = false;
149 | private boolean doGet = true;
150 | private boolean openLog = true;
151 | private ParametersBuilder parametersBuilder = null;
152 | private PropertyBuilder propertyBuilder = new PropertyBuilder();
153 | private int connectTimeout = 5000;
154 | private int readTimeout = 5000;
155 | private ConnectFinishListener connectFinishListener = null;
156 |
157 | public Builder(String url) {
158 | this.url = url;
159 | }
160 |
161 | public Builder connectFinishListener(ConnectFinishListener connectFinishListener) {
162 | this.connectFinishListener = connectFinishListener;
163 | return this;
164 | }
165 |
166 | public Builder url(String url) {
167 | this.url = url;
168 | return this;
169 | }
170 |
171 | public Builder encodeType(String encodeType) {
172 | this.encodeType = encodeType;
173 | return this;
174 | }
175 |
176 | public Builder doGet() {
177 | doGet = true;
178 | return this;
179 | }
180 |
181 | public Builder doPost(ParametersBuilder parametersBuilder) {
182 | this.doGet = false;
183 | this.parametersBuilder = parametersBuilder;
184 | return this;
185 | }
186 |
187 | public Builder doPostAppend(String append) {
188 | this.doGet = false;
189 | this.url += append;
190 | return this;
191 | }
192 |
193 | public Builder property(PropertyBuilder property) {
194 | this.propertyBuilder = property;
195 | return this;
196 | }
197 |
198 | public Builder maxThreadCount(int maxThreadCount) {
199 | this.maxThreadCount = maxThreadCount;
200 | return this;
201 | }
202 |
203 | public Builder connectTimeout(int connectTimeout) {
204 | this.connectTimeout = connectTimeout;
205 | return this;
206 | }
207 |
208 | public Builder readTimeout(int readTimeout) {
209 | this.readTimeout = readTimeout;
210 | return this;
211 | }
212 |
213 | public Builder reLocation(boolean reLocation) {
214 | this.reLocation = reLocation;
215 | return this;
216 | }
217 |
218 | public Builder openLog(boolean openLog) {
219 | this.openLog = openLog;
220 | return this;
221 | }
222 |
223 | public NetUtil build() {
224 | return new NetUtil(this);
225 | }
226 | }
227 |
228 | public interface ConnectFinishListener {
229 | void onFinish(String result);
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/.idea/uiDesigner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 | -
9 |
10 |
11 | -
12 |
13 |
14 | -
15 |
16 |
17 | -
18 |
19 |
20 |
21 |
22 |
23 | -
24 |
25 |
26 |
27 |
28 |
29 | -
30 |
31 |
32 |
33 |
34 |
35 | -
36 |
37 |
38 |
39 |
40 |
41 | -
42 |
43 |
44 |
45 |
46 | -
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 |
56 | -
57 |
58 |
59 |
60 |
61 | -
62 |
63 |
64 |
65 |
66 | -
67 |
68 |
69 |
70 |
71 | -
72 |
73 |
74 | -
75 |
76 |
77 |
78 |
79 | -
80 |
81 |
82 |
83 |
84 | -
85 |
86 |
87 |
88 |
89 | -
90 |
91 |
92 |
93 |
94 | -
95 |
96 |
97 |
98 |
99 | -
100 |
101 |
102 | -
103 |
104 |
105 | -
106 |
107 |
108 | -
109 |
110 |
111 | -
112 |
113 |
114 |
115 |
116 | -
117 |
118 |
119 | -
120 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/src/main.fxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
54 |
60 |
61 |
62 |
63 |
64 |
65 |
70 |
71 |
72 |
73 |
74 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
114 |
115 |
116 |
117 |
118 |
119 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
143 |
144 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
189 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
--------------------------------------------------------------------------------
/src/Main.java:
--------------------------------------------------------------------------------
1 | import javafx.application.Application;
2 | import javafx.fxml.FXMLLoader;
3 | import javafx.scene.Parent;
4 | import javafx.scene.Scene;
5 | import javafx.scene.control.*;
6 | import javafx.stage.Stage;
7 | import util.TimeUtil;
8 | import util.netUtil.NetUtil;
9 | import util.netUtil.ParametersBuilder;
10 | import util.netUtil.PropertyBuilder;
11 | import util.regexUtil.RegexUtil;
12 | import util.regexUtil.UnicodeUtil;
13 |
14 | import java.util.*;
15 |
16 | public class Main extends Application implements NetUtil.ConnectFinishListener {
17 |
18 | //控件
19 | private Button test, start, stop;
20 | private TextField input_target, input_interval, match_left, match_right, schedule_long;
21 | private TextField time_hour, time_minute;
22 | private TextArea tv, input_formData, input_headers;
23 | private Hyperlink hyperlink;
24 |
25 | //配置
26 | private String targetUrl = "", formData = "", headers = "";
27 | private String match_left_string = "", match_right_string = "";
28 | private int interval = 50;
29 | private int hour, minute;
30 | private boolean delay = false;//定时
31 | private Thread delayThread = null;
32 |
33 | //临时变量
34 | private StringBuilder tvContent = new StringBuilder();
35 | private NetUtil netUtil = null;
36 |
37 | //应用密码
38 | private static final String KEY = "ziaiscool";
39 | private static final String URL = "http://zzzia.net:8080/key";
40 | private static final String APPNAME = "netrobot";
41 | private boolean hasKey = false;
42 |
43 | @Override
44 | public void start(Stage primaryStage) throws Exception {
45 | Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
46 | primaryStage.setTitle("NetRobot");
47 | primaryStage.setScene(new Scene(root));
48 | primaryStage.show();
49 |
50 |
51 | primaryStage.setOnCloseRequest(event -> {
52 | primaryStage.close();
53 | try {
54 | stop();
55 | } catch (Exception e) {
56 | e.printStackTrace();
57 | }
58 | });
59 |
60 |
61 | //检查是否有应用使用权
62 | checkPassword(primaryStage);
63 |
64 |
65 | //寻找控件
66 | findId(root);
67 |
68 |
69 | //设置点击事件
70 | //测试按钮
71 | test.setOnAction(event -> {
72 | appendContent("开始测试");
73 | prepareInput();
74 | test();
75 | });
76 |
77 | //开始按钮
78 | start.setOnAction(event -> {
79 | if (!prepareInput()) {
80 | end();
81 | return;
82 | }
83 | start.setDisable(true);
84 | stop.setDisable(false);
85 | if (targetUrl.isEmpty()) return;
86 | if (delay) {
87 | Date targetDate = TimeUtil.getDate(hour, minute);
88 | delayThread = new Thread(() -> {
89 | while (true) {
90 | try {
91 | long restTime = targetDate.getTime() - new Date().getTime();//剩余时间
92 | if (restTime < 1000) {//不到1s,直接开始运行
93 | appendContent("已开始");
94 | long second = 0;
95 | if (!schedule_long.isDisable()) {
96 | second = Long.parseLong(schedule_long.getText());
97 | }
98 | fucking(1000L * second);
99 | break;
100 | } else {
101 | tv.setText("剩余等待时间:" + restTime / 1000 + "秒");
102 | }
103 | Thread.sleep(500L);//由于定时引起的误差,每0.5s检查一次
104 | } catch (InterruptedException e) {
105 | e.printStackTrace();
106 | }
107 | }
108 | });
109 | delayThread.start();
110 | } else {
111 | appendContent("已开始");
112 | fucking();
113 | }
114 | });
115 |
116 | //停止按钮
117 | stop.setOnAction(event -> end());
118 |
119 |
120 | //超链接
121 | hyperlink.setOnAction(event -> {
122 | // try {
123 | // // 创建一个URI实例
124 | // java.net.URI uri = java.net.URI.create("https://github.com/Zzzia/NetRobot");
125 | // // 获取当前系统桌面扩展
126 | // java.awt.Desktop dp = java.awt.Desktop.getDesktop();
127 | // // 判断系统桌面是否支持要执行的功能
128 | // if (dp.isSupported(java.awt.Desktop.Action.BROWSE)) {
129 | // // 获取系统默认浏览器打开链接
130 | // dp.browse(uri);
131 | // }
132 | //
133 | // } catch (Exception e) {
134 | // e.printStackTrace();
135 | // }
136 | });
137 |
138 |
139 | //监听是否定时
140 | time_hour.textProperty().addListener((observable, oldValue, newValue) -> {
141 | if (!newValue.isEmpty()) {
142 | schedule_long.setDisable(false);
143 | } else {
144 | schedule_long.setDisable(true);
145 | }
146 | });
147 |
148 | //关闭软件监听,防止内存泄漏
149 | primaryStage.setOnCloseRequest(event -> {
150 | if (netUtil != null) {
151 | netUtil.stop();
152 | }
153 | });
154 | }
155 |
156 | private void checkPassword(Stage primaryStage) {
157 | try {
158 | String result = new NetUtil
159 | .Builder(URL)
160 | .doPostAppend("/?key=netrobot")
161 | .build()
162 | .connect();
163 | if (!result.contains(KEY)) {
164 | Alert alert = new Alert(Alert.AlertType.INFORMATION);
165 | alert.setTitle("提示");
166 | alert.setContentText("服务器已关闭对该应用的支持");
167 | alert.show();
168 | primaryStage.close();
169 | } else {
170 | hasKey = true;
171 | }
172 | } catch (Exception e) {
173 | e.printStackTrace();
174 | }
175 | }
176 |
177 | private void fucking() {
178 | fucking(0);
179 | }
180 |
181 | private void fucking(long timeout) {
182 | //预留个空指针bug,看谁敢破解密码
183 | netUtil = getBuilder().build();
184 | netUtil.fuckingConnect(interval);
185 | if (timeout != 0) {
186 | Timer timer = new Timer();
187 | timer.schedule(new TimerTask() {
188 | @Override
189 | public void run() {
190 | end();
191 | }
192 | }, timeout);
193 | }
194 | }
195 |
196 | private void test() {
197 | netUtil = getBuilder().build();
198 | netUtil.connect(1);
199 | }
200 |
201 | private void end() {
202 | if (netUtil != null) {
203 | netUtil.stop();
204 | }
205 | if (delayThread != null && delayThread.isAlive()) {
206 | delayThread.stop();
207 | }
208 | start.setDisable(false);
209 | stop.setDisable(true);
210 | appendContent("已结束");
211 | }
212 |
213 | private NetUtil.Builder getBuilder() {
214 | if (!hasKey) return null;
215 | NetUtil.Builder builder = new NetUtil
216 | .Builder(targetUrl)
217 | .openLog(true)
218 | .connectFinishListener(this);
219 | if (!formData.isEmpty()) {
220 | builder = builder.doPost(new ParametersBuilder().put(formData));
221 | } else {
222 | builder = builder.doGet();
223 | }
224 | if (!headers.isEmpty()) {
225 | Map headerMap = new HashMap<>();
226 | String[] headerList = headers.split("\n");
227 | for (String header : headerList) {
228 | String[] property = header.split(":");
229 | if (property.length == 2) {
230 | headerMap.put(property[0].trim(), property[1].trim());
231 | }
232 | }
233 | System.out.println(headers);
234 | PropertyBuilder propertyBuilder = new PropertyBuilder()
235 | .addProperty("Referer", targetUrl)
236 | .addProperty(headerMap);
237 | builder = builder.property(propertyBuilder);
238 | }
239 | return builder;
240 | }
241 |
242 | private void findId(Parent root) {
243 | test = (Button) root.lookup("#button_test");
244 | start = (Button) root.lookup("#button_start");
245 | stop = (Button) root.lookup("#button_stop");
246 | input_target = (TextField) root.lookup("#input_target");
247 | input_interval = (TextField) root.lookup("#input_interval");
248 | time_hour = (TextField) root.lookup("#time_hour");
249 | time_minute = (TextField) root.lookup("#time_minute");
250 | tv = (TextArea) root.lookup("#tv");
251 | input_formData = (TextArea) root.lookup("#input_formData");
252 | input_headers = (TextArea) root.lookup("#input_headers");
253 | match_left = (TextField) root.lookup("#match_left");
254 | match_right = (TextField) root.lookup("#match_right");
255 | hyperlink = (Hyperlink) root.lookup("#hyperlink");
256 | schedule_long = (TextField) root.lookup("#schedule_long");
257 | }
258 |
259 | private boolean prepareInput() {
260 | targetUrl = input_target.getText();
261 | headers = input_headers.getText();
262 | formData = input_formData.getText();
263 | interval = Integer.parseInt(input_interval.getText());
264 | match_left_string = match_left.getText();
265 | match_right_string = match_right.getText();
266 | if (!time_hour.getText().isEmpty() && !time_minute.getText().isEmpty()) {
267 | hour = Integer.parseInt(time_hour.getText());
268 | minute = Integer.parseInt(time_minute.getText());
269 | delay = true;
270 | }
271 | if (targetUrl.isEmpty()) {
272 | appendContent("目标网址不能为空");
273 | return false;
274 | } else if (hour < 0 || hour > 24 || minute < 0 || minute > 60) {
275 | appendContent("时间为24小时制");
276 | return false;
277 | } else {
278 | return true;
279 | }
280 | }
281 |
282 | private void appendContent(String content) {
283 | if (tvContent.length() > 1024 * 1024) {
284 | tvContent = new StringBuilder();
285 | }
286 | tvContent.append(content).append("\n");
287 | tv.setText(tvContent.toString());
288 | tv.setScrollTop(Double.MAX_VALUE);
289 | }
290 |
291 | public static void main(String[] args) {
292 | launch(args);
293 | }
294 |
295 | @Override
296 | public void onFinish(String result) {
297 | if (!match_left_string.isEmpty() && !match_right_string.isEmpty()) {
298 | result = RegexUtil.regexInclude(match_left_string, match_right_string, result).get(0);
299 | }
300 | appendContent(UnicodeUtil.unicodeToString(result));
301 | }
302 | }
303 |
--------------------------------------------------------------------------------