众多bot都有自己的查分功能,为啥我的不行?
我也要搞。
正好放寒假,趁成绩还没出完放松一波,把这个坑填掉。
原网址:Arcaea查分器
#01 分析源数据传输格式
先请求一次,抓一个包看看怎么嫖数据。
进行一次查分请求后获得了如下结果:
从上图可以看出,数据传输时用的协议是WebSocket协议。
查分流程大致如下所示:
继续看数据交换过程,发现查分时的查分数据({data})是用二进制流传输的。下一步就是要将这些二进制数据接码为可读的数据。
观察Request请求头,可发现Accept-Encoding: gzip, deflate, br
一句,表明可能的编码方式为gzip/deflate/brotli。分开测试是不可能测试的,直接看网页缓存,就可发现brotli_decompress.min.js这一表征brotli压缩的js文件。
#02 适配Java平台
是时候展现CTRLC+CTRLV大法了。从别处抄来WebSocket的实现,又从别处抄来了Apache Commons Compress的解压例程,复制粘贴替换一气呵成。
可用的代码如下:
static WebSocketClient client; public static void main(String[] args) { try { client = new WebSocketClient(new URI("wss://arc.estertion.win:616/"), new Draft_6455()) { @Override public void onOpen(ServerHandshake serverHandshake) { System.out.println("握手成功"); } @Override public void onMessage(String msg) { System.out.println("收到消息==========" + msg); if (msg.equals("bye")) { client.close(); } } @Override public void onMessage(ByteBuffer bytes) { try { System.out.println("收到消息字节流消息==========" + new String(BrotliUtil.deCompress(bytes.array()), StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } } @Override public void onClose(int i, String s, boolean b) { System.out.println("链接已关闭"); } @Override public void onError(Exception e) { e.printStackTrace(); System.out.println("发生错误已关闭"); } }; } catch (URISyntaxException e) { e.printStackTrace(); } client.connect(); while (client.getReadyState().equals(ReadyState.NOT_YET_CONNECTED)) { System.out.println("正在连接..."); } while (!client.getReadyState().equals(ReadyState.OPEN)) { System.out.println("仍在连接..."); } //连接成功,发送好友码 client.send("932358780"); }
测试一下,成功获得了查分数据。