├── .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 | 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 | 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 + "[\\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 | 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 | --------------------------------------------------------------------------------