From e22bd12e1275448034d9c6aa611b04f335c3f770 Mon Sep 17 00:00:00 2001 From: RockChin <1010553892@qq.com> Date: Fri, 18 Jun 2021 10:59:07 +0800 Subject: [PATCH] Add support for LegacyPing(server ver 1.6.x) --- .../src/main/conn/MinecraftServer.java | 148 ++++++++++++++++-- .../src/test/conn/FakeServerTest.java | 17 +- .../src/test/conn/LegacyPingTest.java | 72 +++++++++ .../src/test/conn/MinecraftServerTest.java | 4 +- 4 files changed, 215 insertions(+), 26 deletions(-) create mode 100644 BasicInfoAPI/src/test/conn/LegacyPingTest.java diff --git a/BasicInfoAPI/src/main/conn/MinecraftServer.java b/BasicInfoAPI/src/main/conn/MinecraftServer.java index 9c77a32..aa21479 100644 --- a/BasicInfoAPI/src/main/conn/MinecraftServer.java +++ b/BasicInfoAPI/src/main/conn/MinecraftServer.java @@ -6,9 +6,10 @@ import java.io.DataInputStream; import java.io.DataOutputStream; -import java.io.IOException; +import java.io.EOFException; import java.net.Socket; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; /** * A MinecraftServer instance provides methods to create connection to server and communicate with peer. @@ -35,18 +36,105 @@ public MinecraftServer(String host,int port)throws Exception { .addShort(port) .addVarInt(1).write(dataOutputStream); new PacketSend(0).write(dataOutputStream); - response=new Gson().fromJson(new PacketRecv(dataInputStream).popString(),Response.class); - } + try { + response = new Gson().fromJson(new PacketRecv(dataInputStream).popString(), Response.class); + }catch (EOFException e){//To change protocol. + System.out.println("ChangeProtocol"); + socket=new Socket(host,port); + dataInputStream=new DataInputStream(socket.getInputStream()); + dataOutputStream=new DataOutputStream(socket.getOutputStream()); + dataOutputStream.write(0xFE); + dataOutputStream.write(0x01); + dataOutputStream.flush(); - public class Response{ - class description{ + if (dataInputStream.readByte()==-1){ + dataInputStream.readByte(); + dataInputStream.readByte(); + byte[] b=new byte[512]; + dataInputStream.read(b); + ByteBase bbase=new ByteBase(b); + byte[] end=new byte[]{0,0}; + if (new String(bbase.pop(end),StandardCharsets.UTF_16BE).equals("ยง1")){ + System.out.println("packingResponse."); + response=new Response(); + response.version=new Response.version(); + response.version.protocol=Integer.parseInt + (new String(bbase.pop(end),StandardCharsets.UTF_16BE)); + response.version.name=new String(bbase.pop(end),StandardCharsets.UTF_16BE); + response.description=new Response.description(); + response.description.text=new String(bbase.pop(end),StandardCharsets.UTF_16BE); + response.players=new Response.players(); + response.players.online=Integer.parseInt + (new String(bbase.pop(end),StandardCharsets.UTF_16BE)); + response.players.max=Integer.parseInt + (new String(bbase.pop(end),StandardCharsets.UTF_16BE)); + } + } + } + } + private short len(String l){ + String utf16be=new String(l.getBytes(StandardCharsets.UTF_8),StandardCharsets.UTF_16BE); + return (short)utf16be.length(); + } + private void listByte(byte[] bytes){ + System.out.print("list:"); + for(byte b:bytes){ + System.out.print(b+" "); + } + System.out.println(); + } + private class ByteBase{ + byte[] arr; + int index=0; + ByteBase(byte[] byteArr){ + this.arr=byteArr; + for (byte b:byteArr){ + System.out.print(b+" "); + } + System.out.println(); + String s=new String(arr,StandardCharsets.UTF_16BE); + System.out.println(s); + } + public byte[] pop(byte[] end){ + ArrayList byteArrayList=new ArrayList<>(); + byte[] b=new byte[2]; + while(true){ + b=pop(2); + if (b[0]==end[0]&&b[1]==end[1]){ + break; + } + byteArrayList.add(b[0]); + byteArrayList.add(b[1]); + } + int len=byteArrayList.size(); + byte[] result=new byte[len]; + for (int i=0;i