25565 mirror port
This commit is contained in:
parent
060afeeb36
commit
26e0436b91
4 changed files with 119 additions and 3 deletions
2
pom.xml
2
pom.xml
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue