🎉Initial

This commit is contained in:
zhengyi 2024-03-13 18:25:50 +08:00
commit f3d4bb3afc
18 changed files with 520 additions and 0 deletions

40
.gitignore vendored Normal file
View File

@ -0,0 +1,40 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
.idea/
### Mac OS ###
.DS_Store

5
README.md Normal file
View File

@ -0,0 +1,5 @@
# Minecraft Server Status Lib
> 🧪这是一个实验项目!
这是一个 Minecraft(Java Edition) 服务器信息查询的库,提供 `MCStatusUtils` 类进行处理。

22
pom.xml Normal file
View File

@ -0,0 +1,22 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>mcstatus</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Archetype - mcstatus</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,7 @@
package top.mczhengyi.mcstatus;
public class MCStatusUtils {
public static void queryStatus() {
}
}

View File

@ -0,0 +1,4 @@
package top.mczhengyi.mcstatus.bean;
public class MCStatus {
}

View File

@ -0,0 +1,23 @@
package top.mczhengyi.mcstatus.bean.java;
public class JavaPlayer {
private String name;
private String id;
public String getName() {
return name;
}
public String getId() {
return id;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("JavaPlayer{");
sb.append("name='").append(name).append('\'');
sb.append(", id='").append(id).append('\'');
sb.append('}');
return sb.toString();
}
}

View File

@ -0,0 +1,32 @@
package top.mczhengyi.mcstatus.bean.java;
import java.util.List;
public class JavaPlayers {
private int max;
private int online;
private List<JavaPlayer> sample;
public int getMax() {
return max;
}
public int getOnline() {
return online;
}
public List<JavaPlayer> getSample() {
return sample;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("JavaPlayers{");
sb.append("max=").append(max);
sb.append(", online=").append(online);
sb.append(", sample=").append(sample);
sb.append('}');
return sb.toString();
}
}

View File

@ -0,0 +1,85 @@
package top.mczhengyi.mcstatus.bean.java;
public class JavaStatusResponse {
private Description description;
private JavaPlayers players;
private JavaVersion version;
private String favicon;
private int time;
public Description getDescription() {
return description;
}
public JavaPlayers getPlayers() {
return players;
}
public JavaVersion getVersion() {
return version;
}
public String getFavicon() {
return favicon;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public class Description {
private String color;
private String text;
private Description[] extra;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Description[] getExtra() {
return extra;
}
public void setExtra(Description[] extra) {
this.extra = extra;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Description{");
sb.append("color='").append(color).append('\'');
sb.append(", text='").append(text).append('\'');
sb.append(", extra=").append(extra);
sb.append('}');
return sb.toString();
}
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("JavaStatusResponse{");
sb.append("description=").append(description);
sb.append(", players=").append(players);
sb.append(", version=").append(version);
sb.append(", favicon='").append(favicon).append('\'');
sb.append(", time=").append(time);
sb.append('}');
return sb.toString();
}
}

View File

@ -0,0 +1,23 @@
package top.mczhengyi.mcstatus.bean.java;
public class JavaVersion {
private String name;
private String protocol;
public String getName() {
return name;
}
public String getProtocol() {
return protocol;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("JavaVersion{");
sb.append("name='").append(name).append('\'');
sb.append(", protocol='").append(protocol).append('\'');
sb.append('}');
return sb.toString();
}
}

View File

@ -0,0 +1,85 @@
package top.mczhengyi.mcstatus.java;
import com.google.gson.Gson;
import top.mczhengyi.mcstatus.bean.java.JavaStatusResponse;
import top.mczhengyi.mcstatus.utils.VarIntUtils;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
public class Ping {
private InetSocketAddress host;
private int timeout = 7000;
private Gson gson = new Gson();
public Ping(InetSocketAddress host) {
this(host, 3000);
}
public Ping(String hostName, int port) {
this(new InetSocketAddress(hostName, port));
}
public Ping(InetSocketAddress host, int timeout) {
this.host = host;
this.timeout = timeout;
}
public JavaStatusResponse fetchData() throws SocketException {
// Create Socket
try (Socket socket = new Socket()) {
// Setting socket
socket.setSoTimeout(this.timeout);
socket.connect(host, timeout);
OutputStream outputStream = socket.getOutputStream();;
InputStream inputStream = socket.getInputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
// build handshake data
ByteArrayOutputStream b = new ByteArrayOutputStream();
DataOutputStream handshake = new DataOutputStream(b);
handshake.writeByte(0x00); // Packet ID
VarIntUtils.writeVarInt(handshake, -1); // Protocol Version
VarIntUtils.writeVarInt(handshake, host.getHostString().length()); // String Length
handshake.writeBytes(this.host.getHostString()); // Server Address
handshake.writeShort(this.host.getPort());
VarIntUtils.writeVarInt(handshake, 1);
// Send Handshake
VarIntUtils.writeVarInt(dataOutputStream, b.size()); // Length of packet
dataOutputStream.write(b.toByteArray());
// Send Status Query
dataOutputStream.writeByte(0x01);
dataOutputStream.writeByte(0x00);
DataInputStream dataInputStream = new DataInputStream(inputStream);
int size = VarIntUtils.readVarInt(dataInputStream); // Read Packet Size
int id = VarIntUtils.readVarInt(dataInputStream); // Read Packet Id
// Read JSON String
int length = VarIntUtils.readVarInt(dataInputStream); // Read String Length
byte[] jsonBytes = new byte[length];
dataInputStream.readFully(jsonBytes);
String json = new String(jsonBytes);
return gson.fromJson(json, JavaStatusResponse.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void setAddress(InetSocketAddress host) {
this.host = host;
}
public InetSocketAddress getAddress() {
return this.host;
}
void setTimeout(int timeout) {
this.timeout = timeout;
}
int getTimeout() {
return this.timeout;
}
}

View File

@ -0,0 +1,57 @@
package top.mczhengyi.mcstatus.utils;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class VarIntUtils {
private static final int SEGMENT_BITS = 0x7F;
private static final int CONTINUE_BIT = 0x80;
public static int readVarInt(DataInputStream in) throws IOException {
int value = 0;
int position = 0;
byte currentByte;
while (true) {
currentByte = in.readByte();
value |= (currentByte & SEGMENT_BITS) << position;
if ((currentByte & CONTINUE_BIT) == 0) break;
position += 7;
if (position >= 32) throw new RuntimeException("VarInt is too Big");
}
return value;
}
public static long readVarLong(DataInputStream in) throws IOException {
long value = 0;
int position = 0;
byte currentByte;
while (true) {
currentByte = in.readByte();
value |= (long) (currentByte & SEGMENT_BITS) << position;
if ((currentByte & CONTINUE_BIT) == 0) break;
position += 7;
if (position >= 64) throw new RuntimeException("VarLong is too big");
}
return value;
}
public static void writeVarInt(DataOutputStream out, int value) throws IOException {
while (true) {
if ((value & ~SEGMENT_BITS) == 0) {
out.writeByte(value);
return;
}
out.writeByte((value & SEGMENT_BITS) | CONTINUE_BIT);
value >>>= 7;
}
}
}

View File

@ -0,0 +1,9 @@
<archetype>
<id>mcstatus</id>
<sources>
<source>src/main/java/App.java</source>
</sources>
<testSources>
<source>src/test/java/AppTest.java</source>
</testSources>
</archetype>

View File

@ -0,0 +1,15 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>$org.example</groupId>
<artifactId>$mcstatus</artifactId>
<version>$1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,13 @@
package $org.example;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}

View File

@ -0,0 +1,38 @@
package $org.example;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest
extends TestCase
{
/**
* Create the test case
*
* @param testName name of the test case
*/
public AppTest( String testName )
{
super( testName );
}
/**
* @return the suite of tests being tested
*/
public static Test suite()
{
return new TestSuite( AppTest.class );
}
/**
* Rigourous Test :-)
*/
public void testApp()
{
assertTrue( true );
}
}

View File

@ -0,0 +1,9 @@
import org.junit.jupiter.api.Test;
import java.net.InetSocketAddress;
public class PingTest {
@Test
public void fetchData() {
}
}

View File

@ -0,0 +1,26 @@
package top.mczhengyi.mcstatus.java;
import org.junit.jupiter.api.Test;
import java.net.SocketException;
import static org.junit.jupiter.api.Assertions.*;
class PingTest {
@Test
public void fetchData() throws SocketException {
Ping ping1 = new Ping("play.mczhengyi.top", 25577);
System.out.println(ping1.fetchData());
Ping ping = new Ping("pe.youpixel.cn", 19900);
System.out.println(ping.fetchData());
Ping ping3 = new Ping("mc.vancraft.cn", 25565);
System.out.println(ping3.fetchData());
Ping ping4 = new Ping("s1.mcsol.cn", 9879);
System.out.println(ping4.fetchData());
}
}

View File

@ -0,0 +1,27 @@
package top.mczhengyi.mcstatus.utils;
import org.junit.jupiter.api.Test;
import java.io.*;
import static org.junit.jupiter.api.Assertions.*;
class VarIntUtilsTest {
@Test
void readVarInt() throws IOException {
DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(new byte[]{-1, -1, -1, -1, 15}));
System.out.println(VarIntUtils.readVarInt(inputStream));
}
@Test
void readVarLong() {
}
@Test
void writeVarInt() throws IOException {
DataOutputStream outputStream = new DataOutputStream(new ByteArrayOutputStream());
VarIntUtils.writeVarInt(outputStream, -1);
System.out.println(outputStream);
}
}