25565 mirror port

This commit is contained in:
Dereku 2024-11-18 21:40:27 +07:00
parent 060afeeb36
commit 26e0436b91
4 changed files with 119 additions and 3 deletions

View file

@ -6,7 +6,7 @@
<groupId>net.rubeta</groupId> <groupId>net.rubeta</groupId>
<artifactId>LegacyPing</artifactId> <artifactId>LegacyPing</artifactId>
<version>1.8</version> <version>2.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>LegacyPing</name> <name>LegacyPing</name>

View file

@ -0,0 +1,106 @@
package net.rubeta.legacyping;
import net.minecraft.network.packets.Packet;
import net.minecraft.network.packets.Packet255KickDisconnect;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.server.ServerListPingEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CrutchBukkitMirrorThread extends Thread {
private final AtomicBoolean working = new AtomicBoolean(false);
private final Logger logger;
private ServerSocket serverSocket;
private final InetAddress address;
private final LegacyPing plugin;
public CrutchBukkitMirrorThread(final LegacyPing plugin) {
this.plugin = plugin;
this.logger = Logger.getLogger("mirror:25565");
try {
this.address = InetAddress.getByName("0.0.0.0");
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
@Override
public void run() {
this.working.set(true);
while (this.working.get()) {
try {
this.serverSocket = new ServerSocket(25565, 10, address);
this.serverSocket.setSoTimeout((int) TimeUnit.SECONDS.toMillis(10L));
this.serverSocket.setPerformancePreferences(0, 2, 1);
} catch (IOException e) {
this.logger.log(Level.WARNING, "Failed to start ServerSocket", e);
this.pause();
continue;
}
while (!this.serverSocket.isClosed()) {
if (!this.working.get()) {
break;
}
InetAddress address = null;
try (final Socket socket = this.serverSocket.accept()) {
final DataInputStream inputStream = new DataInputStream(socket.getInputStream());
final DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
address = socket.getInetAddress();
socket.setTrafficClass(SocketOptions.TCP_NODELAY & SocketOptions.IP_TOS);
inputStream.readInt(); // Packet length
Packet packet = Packet.readPacket(inputStream);
if (packet != null && packet.getPacketId() == 254) {
CraftServer server = (CraftServer) this.plugin.getServer();
ServerListPingEvent pingEvent = CraftEventFactory.callServerListPingEvent(
server, address, server.getServer().motd,
server.getOnlinePlayers().length, server.getMaxPlayers()
);
String s = pingEvent.getMotd() + "\u0000" + server.getOnlinePlayers().length + "\u0000" + pingEvent.getMaxPlayers();
Packet255KickDisconnect response = new Packet255KickDisconnect(s);
outputStream.writeInt(s.length() + 1);
outputStream.writeByte(255);
response.writePacketData(outputStream);
}
} catch (SocketTimeoutException | EOFException ignore) {
} catch (Exception ex) {
this.logger.warning("An exception occurred while communicating with " + address);
this.logger.log(Level.WARNING, "Exception in " + this.getName(), ex);
}
}
}
}
public void shutdown() {
this.working.set(false);
try {
this.serverSocket.close();
} catch (IOException ignore) {
}
}
void pause() {
this.pause(TimeUnit.SECONDS.toMillis(30L));
}
void pause(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException ignored) {
}
}
}

View file

@ -13,6 +13,7 @@ import java.util.logging.Level;
public final class LegacyPing extends JavaPlugin { public final class LegacyPing extends JavaPlugin {
private final List<ServerThread> threads = new ArrayList<>(); private final List<ServerThread> threads = new ArrayList<>();
private CrutchBukkitMirrorThread mirror = null;
@Override @Override
public void onEnable() { public void onEnable() {
@ -33,11 +34,18 @@ public final class LegacyPing extends JavaPlugin {
this.getLogger().log(Level.WARNING, "Failed to create ServerSocket", e); this.getLogger().log(Level.WARNING, "Failed to create ServerSocket", e);
} }
} }
if (config.getBoolean("enableMirrorPort", false)) {
this.mirror = new CrutchBukkitMirrorThread(this);
this.mirror.start();
}
this.threads.forEach(Thread::start); this.threads.forEach(Thread::start);
} }
@Override @Override
public void onDisable() { public void onDisable() {
if (this.mirror != null) {
this.mirror.shutdown();
}
this.threads.forEach(ServerThread::shutdown); this.threads.forEach(ServerThread::shutdown);
} }
@ -46,7 +54,9 @@ public final class LegacyPing extends JavaPlugin {
if (!sender.isOp()) { if (!sender.isOp()) {
return true; return true;
} }
if (this.mirror != null) {
this.mirror.shutdown();
}
this.threads.forEach(ServerThread::shutdown); this.threads.forEach(ServerThread::shutdown);
this.threads.clear(); this.threads.clear();
this.startThreads(); this.startThreads();

View file

@ -50,7 +50,7 @@ public class ServerThread extends Thread {
} }
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
new ServerThread("", 25565).start(); new ServerThread("", 25569).start();
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")