众多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");
}
测试一下,成功获得了查分数据。
