Files
Purpur/patches/server/0089-UPnP-Port-Forwarding-Service.patch
William Blake Galbreath fc7824b3a8 Updated Upstream (Paper)
Upstream has released updates that appears to apply and compile correctly

Paper Changes:
f29c7ebd Improve async login (#3189)
9fd36824 Fix Citizens Player NPC tracking issue - Fixes #3186
0e72de1c Fix Player Tracking issue during join process.
f26362af Load Spawn Chunks Asynchronously and Spiral Out
54f762e2 Load Chunks for Login Asynchronously
f2d1b6e5 Clean up duplicate PlayerInitialSpawnEvent
c2d022d7 Fix Longstanding Broken behavior of PlayerJoinEvent
d0a348b9 Broadcast join messages to console
1ef687a4 Don't crash if player is attempted to be removed from untracked chunk.
c11668ac Make sure the chunk conversion task is executed immediately
26fb7cc3 Fix Chunk Post Processing deadlock risk
2020-04-19 17:06:16 -05:00

201 lines
8.0 KiB
Diff

From 64bdc122b1f0d98447a1cd146feea09d134d5ead Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Wed, 22 Jan 2020 20:13:40 -0600
Subject: [PATCH] UPnP Port Forwarding Service
---
pom.xml | 10 ++++
.../net/minecraft/server/DedicatedServer.java | 25 ++++++++++
.../net/minecraft/server/MinecraftServer.java | 10 ++++
.../java/net/pl3x/purpur/PurpurConfig.java | 5 ++
.../net/pl3x/purpur/gui/info/JInfoPanel.java | 3 ++
.../pl3x/purpur/gui/info/UPnPComponent.java | 47 +++++++++++++++++++
6 files changed, 100 insertions(+)
create mode 100644 src/main/java/net/pl3x/purpur/gui/info/UPnPComponent.java
diff --git a/pom.xml b/pom.xml
index a7ee9396a0..93fba088f4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,6 +53,12 @@
<version>1.7.7.1</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>com.dosse.upnp</groupId>
+ <artifactId>UPnP</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
<!-- Purpur end -->
<dependency>
<groupId>net.minecrell</groupId>
@@ -146,6 +152,10 @@
<id>spigotmc-public</id>
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
</repository>
+ <repository>
+ <id>pl3x</id>
+ <url>https://repo.pl3x.net/</url>
+ </repository>
</repositories>
<pluginRepositories>
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index fe474e4eba..18fdaf53ef 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -241,6 +241,31 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
return false;
}
+ // Purpur start
+ if (net.pl3x.purpur.PurpurConfig.useUPnP) {
+ LOGGER.info("[UPnP] Attempting to start UPnP port forwarding service...");
+ com.dosse.upnp.UPnP.NAME = "Purpur UPnP";
+ if (com.dosse.upnp.UPnP.isUPnPAvailable()) {
+ if (com.dosse.upnp.UPnP.isMappedTCP(getPort())) {
+ upnp = false;
+ LOGGER.info("[UPnP] Port " + getPort() + " is already open");
+ } else if (com.dosse.upnp.UPnP.openPortTCP(getPort())) {
+ upnp = true;
+ LOGGER.info("[UPnP] Successfully opened port " + getPort());
+ } else {
+ upnp = false;
+ LOGGER.info("[UPnP] Failed to open port " + getPort());
+ }
+ if (upnp) {
+ LOGGER.info("[UPnP] " + com.dosse.upnp.UPnP.getExternalIP() + ":" + getPort());
+ }
+ } else {
+ upnp = false;
+ LOGGER.error("[UPnP] Service is unavailable");
+ }
+ }
+ // Purpur end
+
// CraftBukkit start
// this.a((PlayerList) (new DedicatedPlayerList(this))); // Spigot - moved up
server.loadPlugins();
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 64aeaaaec1..0ae6a9760e 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -187,6 +187,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
public boolean lagging = false; // Purpur
public final SlackActivityAccountant slackActivityAccountant = new SlackActivityAccountant();
// Spigot end
+ protected boolean upnp = false; public boolean isUPnPEnabled() { return upnp; } // Purpur
public MinecraftServer(OptionSet options, Proxy proxy, DataFixer datafixer, CommandDispatcher commanddispatcher, YggdrasilAuthenticationService yggdrasilauthenticationservice, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache, WorldLoadListenerFactory worldloadlistenerfactory, String s) {
super("Server");
@@ -737,6 +738,15 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// CraftBukkit end
MinecraftServer.LOGGER.info("Stopping server");
MinecraftTimings.stopServer(); // Paper
+ // Purpur start
+ if (upnp) {
+ if (com.dosse.upnp.UPnP.closePortTCP(getPort())) {
+ LOGGER.info("[UPnP] Port " + getPort() + " closed");
+ } else {
+ LOGGER.error("[UPnP] Failed to close port " + getPort());
+ }
+ }
+ // Purpur end
// CraftBukkit start
if (this.server != null) {
this.server.disablePlugins();
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
index 16f5c9d372..c4ec515557 100644
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
@@ -154,6 +154,11 @@ public class PurpurConfig {
useAlternateKeepAlive = getBoolean("settings.use-alternate-keepalive", useAlternateKeepAlive);
}
+ public static boolean useUPnP = false;
+ private static void upnpSettings() {
+ useUPnP = getBoolean("settings.upnp-port-forwarding", useUPnP);
+ }
+
public static boolean dontSendUselessEntityPackets = false;
private static void dontSendUselessEntityPackets() {
dontSendUselessEntityPackets = getBoolean("settings.dont-send-useless-entity-packets", dontSendUselessEntityPackets);
diff --git a/src/main/java/net/pl3x/purpur/gui/info/JInfoPanel.java b/src/main/java/net/pl3x/purpur/gui/info/JInfoPanel.java
index c4903c7db6..ee4f022fc5 100644
--- a/src/main/java/net/pl3x/purpur/gui/info/JInfoPanel.java
+++ b/src/main/java/net/pl3x/purpur/gui/info/JInfoPanel.java
@@ -19,13 +19,16 @@ public class JInfoPanel extends JPanel {
ramGraph = new RAMGraph();
RAMDetails ramDetails = new RAMDetails(server);
+ UPnPComponent upnpComponent = new UPnPComponent(server);
add(ramGraph, "North");
add(ramDetails, "Center");
+ add(upnpComponent, "South");
timer = new Timer(500, (event) -> {
ramGraph.update();
ramDetails.update();
+ upnpComponent.repaint();
});
timer.start();
}
diff --git a/src/main/java/net/pl3x/purpur/gui/info/UPnPComponent.java b/src/main/java/net/pl3x/purpur/gui/info/UPnPComponent.java
new file mode 100644
index 0000000000..b0465d3608
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/gui/info/UPnPComponent.java
@@ -0,0 +1,47 @@
+package net.pl3x.purpur.gui.info;
+
+import net.minecraft.server.MinecraftServer;
+import net.pl3x.purpur.PurpurConfig;
+
+import javax.swing.JTextPane;
+import javax.swing.border.EmptyBorder;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+
+public class UPnPComponent extends JTextPane {
+ private final MinecraftServer server;
+
+ public UPnPComponent(MinecraftServer server) {
+ this.server = server;
+ setBorder(new EmptyBorder(0, 30, 0, 10));
+ setEditable(false);
+ setText("UPnP Status");
+ setOpaque(false);
+ setHighlighter(null);
+ }
+
+ @Override
+ public Dimension getPreferredSize() {
+ return new Dimension(350, 20);
+ }
+
+ @Override
+ public void paint(Graphics graphics) {
+ super.paint(graphics);
+ graphics.setColor(server.isUPnPEnabled() ? Color.GREEN : Color.RED);
+ graphics.fillOval(10, 0, 15, 15);
+ setToolTipText(getTooltip());
+ }
+
+ private String getTooltip() {
+ if (!PurpurConfig.useUPnP) {
+ return "UPnP Disabled";
+ }
+ if (server.isUPnPEnabled()) {
+ return "UPnP Enabled";
+ } else {
+ return "UPnP Unavailable";
+ }
+ }
+}
--
2.24.0