From 3e4f2445524459f61b33a62a76b02c463fd1a716 Mon Sep 17 00:00:00 2001 From: Dereku Date: Fri, 10 Mar 2023 05:29:18 +0700 Subject: [PATCH] Init --- .gitignore | 113 ++++++++++++++++++ pom.xml | 63 ++++++++++ .../net/rubeta/legacyping/LegacyPing.java | 31 +++++ .../net/rubeta/legacyping/ServerThread.java | 79 ++++++++++++ src/main/resources/config.yml | 2 + src/main/resources/plugin.yml | 3 + 6 files changed, 291 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/net/rubeta/legacyping/LegacyPing.java create mode 100644 src/main/java/net/rubeta/legacyping/ServerThread.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..2039174 --- /dev/null +++ b/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + net.rubeta + LegacyPing + 1.0-SNAPSHOT + jar + + LegacyPing + + + 1.8 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + + + + + + src/main/resources + true + + + + + + + org.bukkit + crutchbukkitmodded + 0.0.1-SNAPSHOT + provided + + + diff --git a/src/main/java/net/rubeta/legacyping/LegacyPing.java b/src/main/java/net/rubeta/legacyping/LegacyPing.java new file mode 100644 index 0000000..c6dc71a --- /dev/null +++ b/src/main/java/net/rubeta/legacyping/LegacyPing.java @@ -0,0 +1,31 @@ +package net.rubeta.legacyping; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.IOException; +import java.util.logging.Level; + +public final class LegacyPing extends JavaPlugin { + private ServerThread serverThread; + + @Override + public void onEnable() { + this.saveDefaultConfig(); + final FileConfiguration config = this.getConfig(); + try { + this.serverThread = new ServerThread(this.getServer(), config.getString("host", "0.0.0.0"), config.getInt("port", 25566)); + this.serverThread.start(); + } catch (IOException e) { + this.getLogger().log(Level.WARNING, "Failed to create ServerSocket", e); + this.getPluginLoader().disablePlugin(this); + } + } + + @Override + public void onDisable() { + if (this.serverThread != null) { + this.serverThread.shutdown(); + } + } +} diff --git a/src/main/java/net/rubeta/legacyping/ServerThread.java b/src/main/java/net/rubeta/legacyping/ServerThread.java new file mode 100644 index 0000000..e656f33 --- /dev/null +++ b/src/main/java/net/rubeta/legacyping/ServerThread.java @@ -0,0 +1,79 @@ +package net.rubeta.legacyping; + +import org.bukkit.Server; + +import java.io.*; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +public class ServerThread extends Thread { + + // Queries start + private static final byte[] RUBETA_MODDED_CLIENT = new byte[]{0, 0, 0, 1, (byte) 254}; + + // Queries end + private final ServerSocket serverSocket; + private final AtomicBoolean working = new AtomicBoolean(false); + private final Server minecraftServer; + + public ServerThread(final Server server, final String host, int port) throws IOException { + this.minecraftServer = server; + final InetAddress address = InetAddress.getByName(host); + this.serverSocket = new ServerSocket(port, 10, address); + this.serverSocket.setSoTimeout((int) TimeUnit.SECONDS.toMillis(10L)); + } + + @Override + public void run() { + this.working.set(true); + while (this.working.get() || !this.serverSocket.isClosed()) { + try { + final Socket newConnection = this.serverSocket.accept(); + final InputStream inputStream = newConnection.getInputStream(); + final ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[16]; + for (int length; (length = inputStream.read(buffer)) != -1; ) { + result.write(buffer, 0, length); + } + final byte[] query = result.toByteArray(); + final OutputStream outputStream = newConnection.getOutputStream(); + if (Arrays.equals(RUBETA_MODDED_CLIENT, query)) { + this.responseForRuBetaModdedClient(outputStream); + } else if (false) { + + } + newConnection.close(); + } catch (IOException ignore) { + } + } + } + + public void shutdown() { + this.working.set(false); + try { + this.serverSocket.close(); + } catch (IOException ignore) { + } + } + + private void responseForRuBetaModdedClient(final OutputStream outputStream) throws IOException { + final ByteArrayOutputStream result = new ByteArrayOutputStream(); + final DataOutputStream dos = new DataOutputStream(result); + dos.write(255); // Packet 0xFF (PacketDisconnect) + final String response = this.minecraftServer.getMotd() + + '\u0000' + this.minecraftServer.getOnlinePlayers().size() + + '\u0000' + this.minecraftServer.getMaxPlayers(); + dos.writeShort(response.length()); + for (char c : response.toCharArray()) { + dos.writeChar(c); + } + // Packet data end + final DataOutputStream clientOutput = new DataOutputStream(outputStream); + clientOutput.writeInt(result.size()); + clientOutput.write(result.toByteArray()); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..80fd168 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,2 @@ +host: '0.0.0.0' +port: 25566 \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..284ec33 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,3 @@ +name: LegacyPing +version: '${project.version}' +main: net.rubeta.legacyping.LegacyPing