diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeDumpInfo.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeDumpInfo.java
new file mode 100644
index 000000000..547011162
--- /dev/null
+++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeeDumpInfo.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *  THE SOFTWARE.
+ *
+ *  @author GeyserMC
+ *  @link https://github.com/GeyserMC/Geyser
+ *
+ */
+
+package org.geysermc.platform.bungeecord;
+
+import lombok.Getter;
+import net.md_5.bungee.api.ProxyServer;
+import net.md_5.bungee.api.plugin.Plugin;
+import org.geysermc.connector.dump.BootstrapDumpInfo;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@Getter
+public class GeyserBungeeDumpInfo extends BootstrapDumpInfo {
+
+    private String platformName;
+    private String platformVersion;
+    private boolean onlineMode;
+    private List<ListenerInfo> listeners;
+    private List<PluginInfo> plugins;
+
+    GeyserBungeeDumpInfo(ProxyServer proxy) {
+        super();
+        this.platformName = proxy.getName();
+        this.platformVersion = proxy.getVersion();
+        this.onlineMode = proxy.getConfig().isOnlineMode();
+        this.listeners = new ArrayList<>();
+        this.plugins = new ArrayList<>();
+
+        for (net.md_5.bungee.api.config.ListenerInfo listener : proxy.getConfig().getListeners()) {
+            this.listeners.add(new ListenerInfo(listener.getHost().getHostString(), listener.getHost().getPort()));
+        }
+
+        for (Plugin plugin : proxy.getPluginManager().getPlugins()) {
+            this.plugins.add(new PluginInfo(true, plugin.getDescription().getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), Arrays.asList(plugin.getDescription().getAuthor())));
+        }
+    }
+}
diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java
index 1cf519c0e..ec267924f 100644
--- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java
+++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/GeyserBungeePlugin.java
@@ -35,6 +35,7 @@ import org.geysermc.connector.GeyserConnector;
 import org.geysermc.connector.bootstrap.GeyserBootstrap;
 import org.geysermc.connector.command.CommandManager;
 import org.geysermc.connector.configuration.GeyserConfiguration;
+import org.geysermc.connector.dump.BootstrapDumpInfo;
 import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
 import org.geysermc.connector.ping.IGeyserPingPassthrough;
 import org.geysermc.connector.utils.FileUtils;
@@ -140,4 +141,9 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
     public Path getConfigFolder() {
         return getDataFolder().toPath();
     }
+
+    @Override
+    public BootstrapDumpInfo getDumpInfo() {
+        return new GeyserBungeeDumpInfo(getProxy());
+    }
 }
diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotDumpInfo.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotDumpInfo.java
new file mode 100644
index 000000000..01d513fa8
--- /dev/null
+++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotDumpInfo.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *  THE SOFTWARE.
+ *
+ *  @author GeyserMC
+ *  @link https://github.com/GeyserMC/Geyser
+ *
+ */
+
+package org.geysermc.platform.spigot;
+
+import lombok.Getter;
+import org.bukkit.Bukkit;
+import org.bukkit.plugin.Plugin;
+import org.geysermc.connector.dump.BootstrapDumpInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Getter
+public class GeyserSpigotDumpInfo extends BootstrapDumpInfo {
+
+    private String platformName;
+    private String platformVersion;
+    private String platformAPIVersion;
+    private boolean onlineMode;
+    private String serverIP;
+    private int serverPort;
+    private List<PluginInfo> plugins;
+
+    GeyserSpigotDumpInfo() {
+        super();
+        this.platformName = Bukkit.getName();
+        this.platformVersion = Bukkit.getVersion();
+        this.platformAPIVersion = Bukkit.getBukkitVersion();
+        this.onlineMode = Bukkit.getOnlineMode();
+        this.serverIP = Bukkit.getIp();
+        this.serverPort = Bukkit.getPort();
+        this.plugins = new ArrayList<>();
+
+        for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
+            this.plugins.add(new PluginInfo(plugin.isEnabled(), plugin.getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), plugin.getDescription().getAuthors()));
+        }
+    }
+}
diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java
index fd05131a7..7fc493487 100644
--- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java
+++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java
@@ -32,6 +32,7 @@ import org.geysermc.connector.GeyserConnector;
 import org.geysermc.connector.bootstrap.GeyserBootstrap;
 import org.geysermc.connector.command.CommandManager;
 import org.geysermc.connector.configuration.GeyserConfiguration;
+import org.geysermc.connector.dump.BootstrapDumpInfo;
 import org.geysermc.connector.network.translators.world.WorldManager;
 import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
 import org.geysermc.connector.ping.IGeyserPingPassthrough;
@@ -192,4 +193,8 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
         return temp;
     }
 
+    @Override
+    public BootstrapDumpInfo getDumpInfo() {
+        return new GeyserSpigotDumpInfo();
+    }
 }
diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeDumpInfo.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeDumpInfo.java
new file mode 100644
index 000000000..e8f0feaef
--- /dev/null
+++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongeDumpInfo.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *  THE SOFTWARE.
+ *
+ *  @author GeyserMC
+ *  @link https://github.com/GeyserMC/Geyser
+ *
+ */
+
+package org.geysermc.platform.sponge;
+
+import lombok.Getter;
+import org.geysermc.connector.dump.BootstrapDumpInfo;
+import org.spongepowered.api.Platform;
+import org.spongepowered.api.Sponge;
+import org.spongepowered.api.plugin.PluginContainer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Getter
+public class GeyserSpongeDumpInfo extends BootstrapDumpInfo {
+
+    private String platformName;
+    private String platformVersion;
+    private boolean onlineMode;
+    private String serverIP;
+    private int serverPort;
+    private List<PluginInfo> plugins;
+
+    GeyserSpongeDumpInfo() {
+        super();
+        PluginContainer container = Sponge.getPlatform().getContainer(Platform.Component.IMPLEMENTATION);
+        this.platformName = container.getName();
+        this.platformVersion = container.getVersion().get();
+        this.onlineMode = Sponge.getServer().getOnlineMode();
+        this.serverIP = Sponge.getServer().getBoundAddress().get().getHostString();
+        this.serverPort = Sponge.getServer().getBoundAddress().get().getPort();
+        this.plugins = new ArrayList<>();
+
+        for (PluginContainer plugin : Sponge.getPluginManager().getPlugins()) {
+            String pluginClass = plugin.getInstance().map((pl) -> pl.getClass().getName()).orElse("unknown");
+            this.plugins.add(new PluginInfo(true, plugin.getName(), plugin.getVersion().get(), pluginClass, plugin.getAuthors()));
+        }
+    }
+}
diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java
index c5f13b581..abf27749c 100644
--- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java
+++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java
@@ -34,6 +34,7 @@ import org.geysermc.connector.configuration.GeyserConfiguration;
 import org.geysermc.connector.GeyserConnector;
 import org.geysermc.connector.bootstrap.GeyserBootstrap;
 import org.geysermc.connector.command.CommandManager;
+import org.geysermc.connector.dump.BootstrapDumpInfo;
 import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
 import org.geysermc.connector.ping.IGeyserPingPassthrough;
 import org.geysermc.connector.utils.FileUtils;
@@ -162,4 +163,9 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
     public void onServerStop(GameStoppedEvent event) {
         onDisable();
     }
+
+    @Override
+    public BootstrapDumpInfo getDumpInfo() {
+        return new GeyserSpongeDumpInfo();
+    }
 }
diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java
index 0fca35038..c0afd8840 100644
--- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java
+++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/GeyserStandaloneBootstrap.java
@@ -30,6 +30,7 @@ import org.geysermc.connector.GeyserConnector;
 import org.geysermc.connector.bootstrap.GeyserBootstrap;
 import org.geysermc.connector.configuration.GeyserConfiguration;
 import org.geysermc.connector.command.CommandManager;
+import org.geysermc.connector.dump.BootstrapDumpInfo;
 import org.geysermc.connector.ping.IGeyserPingPassthrough;
 import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
 import org.geysermc.connector.utils.FileUtils;
@@ -108,4 +109,9 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
         // Return the current working directory
         return Paths.get(System.getProperty("user.dir"));
     }
+
+    @Override
+    public BootstrapDumpInfo getDumpInfo() {
+        return new BootstrapDumpInfo();
+    }
 }
diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityDumpInfo.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityDumpInfo.java
new file mode 100644
index 000000000..906a04142
--- /dev/null
+++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityDumpInfo.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *  THE SOFTWARE.
+ *
+ *  @author GeyserMC
+ *  @link https://github.com/GeyserMC/Geyser
+ *
+ */
+
+package org.geysermc.platform.velocity;
+
+import com.velocitypowered.api.plugin.PluginContainer;
+import com.velocitypowered.api.proxy.ProxyServer;
+import lombok.Getter;
+import org.geysermc.connector.dump.BootstrapDumpInfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Getter
+public class GeyserVelocityDumpInfo extends BootstrapDumpInfo {
+
+    private String platformName;
+    private String platformVersion;
+    private String platformVendor;
+    private boolean onlineMode;
+    private String serverIP;
+    private int serverPort;
+    private List<PluginInfo> plugins;
+
+    GeyserVelocityDumpInfo(ProxyServer proxy) {
+        super();
+        this.platformName = proxy.getVersion().getName();
+        this.platformVersion = proxy.getVersion().getVersion();
+        this.platformVendor = proxy.getVersion().getVendor();
+        this.onlineMode = proxy.getConfiguration().isOnlineMode();
+        this.serverIP = proxy.getBoundAddress().getHostString();
+        this.serverPort = proxy.getBoundAddress().getPort();
+        this.plugins = new ArrayList<>();
+
+        for (PluginContainer plugin : proxy.getPluginManager().getPlugins()) {
+            String pluginClass = plugin.getInstance().map((pl) -> pl.getClass().getName()).orElse("unknown");
+            this.plugins.add(new PluginInfo(true, plugin.getDescription().getName().get(), plugin.getDescription().getVersion().get(), pluginClass, plugin.getDescription().getAuthors()));
+        }
+    }
+}
diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java
index 5abf3c230..1116fb8c8 100644
--- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java
+++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPlugin.java
@@ -39,6 +39,7 @@ import org.geysermc.common.PlatformType;
 import org.geysermc.connector.configuration.GeyserConfiguration;
 import org.geysermc.connector.GeyserConnector;
 import org.geysermc.connector.bootstrap.GeyserBootstrap;
+import org.geysermc.connector.dump.BootstrapDumpInfo;
 import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
 import org.geysermc.connector.ping.IGeyserPingPassthrough;
 import org.geysermc.connector.utils.FileUtils;
@@ -153,4 +154,9 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
     public void onShutdown(ProxyShutdownEvent event) {
         onDisable();
     }
+
+    @Override
+    public BootstrapDumpInfo getDumpInfo() {
+        return new GeyserVelocityDumpInfo(proxyServer);
+    }
 }
diff --git a/common/src/main/java/org/geysermc/common/serializer/AsteriskSerializer.java b/common/src/main/java/org/geysermc/common/serializer/AsteriskSerializer.java
new file mode 100644
index 000000000..9772a8e31
--- /dev/null
+++ b/common/src/main/java/org/geysermc/common/serializer/AsteriskSerializer.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *  THE SOFTWARE.
+ *
+ *  @author GeyserMC
+ *  @link https://github.com/GeyserMC/Geyser
+ *
+ */
+
+package org.geysermc.common.serializer;
+
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.ContextualSerializer;
+import com.fasterxml.jackson.databind.ser.std.StdSerializer;
+
+import java.io.IOException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.Optional;
+
+public class AsteriskSerializer extends StdSerializer<Object> implements ContextualSerializer {
+    @Target({ElementType.FIELD})
+    @Retention(RetentionPolicy.RUNTIME)
+    @JacksonAnnotationsInside
+    @JsonSerialize(using = AsteriskSerializer.class)
+    public @interface Asterisk {
+        String value() default "***";
+    }
+
+    String asterisk;
+
+    public AsteriskSerializer() {
+        super(Object.class);
+    }
+
+    public AsteriskSerializer(String asterisk) {
+        super(Object.class);
+        this.asterisk = asterisk;
+    }
+
+    @Override
+    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) {
+        Optional<Asterisk> anno = Optional.ofNullable(property)
+                .map(prop -> prop.getAnnotation(Asterisk.class));
+        return new AsteriskSerializer(anno.map(Asterisk::value).orElse(null));
+    }
+
+    @Override
+    public void serialize(Object obj, JsonGenerator gen, SerializerProvider prov) throws IOException {
+        gen.writeString(asterisk);
+    }
+}
diff --git a/connector/pom.xml b/connector/pom.xml
index eaa2801e9..9526c840d 100644
--- a/connector/pom.xml
+++ b/connector/pom.xml
@@ -170,6 +170,11 @@
                     <skipPoms>false</skipPoms>
                     <excludeProperties>
                         <excludeProperty>git.user.*</excludeProperty>
+                        <excludeProperty>git.*.user.*</excludeProperty>
+                        <excludeProperty>git.closest.*</excludeProperty>
+                        <excludeProperty>git.commit.id.describe</excludeProperty>
+                        <excludeProperty>git.commit.id.describe-short</excludeProperty>
+                        <excludeProperty>git.commit.message.short</excludeProperty>
                     </excludeProperties>
                     <commitIdGenerationMode>flat</commitIdGenerationMode>
                     <gitDescribe>
diff --git a/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java
index 8683f80cd..f089350fb 100644
--- a/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java
+++ b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java
@@ -26,6 +26,7 @@
 
 package org.geysermc.connector.bootstrap;
 
+import org.geysermc.connector.dump.BootstrapDumpInfo;
 import org.geysermc.connector.ping.IGeyserPingPassthrough;
 import org.geysermc.connector.configuration.GeyserConfiguration;
 import org.geysermc.connector.GeyserLogger;
@@ -92,4 +93,11 @@ public interface GeyserBootstrap {
      * @return Path location of data folder
      */
     Path getConfigFolder();
+
+    /**
+     * Information used for the bootstrap section of the debug dump
+     *
+     * @return The info about the bootstrap
+     */
+    BootstrapDumpInfo getDumpInfo();
 }
diff --git a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java
index 8b1d0bc78..217a9df1f 100644
--- a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java
+++ b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java
@@ -49,6 +49,7 @@ public abstract class CommandManager {
         registerCommand(new ReloadCommand(connector, "reload", "Reloads the Geyser configurations. Kicks all players when used!", "geyser.command.reload"));
         registerCommand(new StopCommand(connector, "stop", "Shuts down Geyser.", "geyser.command.stop"));
         registerCommand(new OffhandCommand(connector, "offhand", "Puts an items in your offhand.", "geyser.command.offhand"));
+        registerCommand(new DumpCommand(connector, "dump", "Dumps Geyser debug infomation for bug reports.", "geyser.command.dump"));
     }
 
     public void registerCommand(GeyserCommand command) {
diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java
new file mode 100644
index 000000000..4dbb3bb37
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @author GeyserMC
+ * @link https://github.com/GeyserMC/Geyser
+ */
+
+package org.geysermc.connector.command.defaults;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
+import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
+import org.geysermc.common.ChatColor;
+import org.geysermc.connector.GeyserConnector;
+import org.geysermc.connector.command.CommandSender;
+import org.geysermc.connector.command.GeyserCommand;
+import org.geysermc.connector.dump.DumpInfo;
+import org.geysermc.connector.utils.WebUtils;
+
+import java.io.IOException;
+
+public class DumpCommand extends GeyserCommand {
+
+    private final GeyserConnector connector;
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+    private static final String DUMP_URL = "https://dump.geysermc.org/";
+
+    public DumpCommand(GeyserConnector connector, String name, String description, String permission) {
+        super(name, description, permission);
+
+        this.connector = connector;
+
+        final SimpleFilterProvider filter = new SimpleFilterProvider();
+        filter.addFilter("dump_user_auth", SimpleBeanPropertyFilter.serializeAllExcept(new String[] {"password"}));
+
+        MAPPER.setFilterProvider(filter);
+    }
+
+    @Override
+    public void execute(CommandSender sender, String[] args) {
+        sender.sendMessage("Collecting dump info");
+        String dumpData = "";
+        try {
+            dumpData = MAPPER.writeValueAsString(new DumpInfo());
+        } catch (IOException e) {
+            sender.sendMessage(ChatColor.RED + "Failed to collect dump info, check console for more information");
+            connector.getLogger().error("Failed to collect dump info", e);
+            return;
+        }
+
+        sender.sendMessage("Uploading dump");
+        String response;
+        JsonNode responseNode;
+        try {
+            response = WebUtils.post(DUMP_URL + "documents", dumpData);
+            responseNode = MAPPER.readTree(response);
+        } catch (IOException e) {
+            sender.sendMessage(ChatColor.RED + "Failed to upload dump, check console for more information");
+            connector.getLogger().error("Failed to upload dump", e);
+            return;
+        }
+
+        if (!responseNode.has("key")) {
+            sender.sendMessage(ChatColor.RED + "Failed to upload dump: " + (responseNode.has("message") ? responseNode.get("message").asText() : response));
+            return;
+        }
+
+        String uploadedDumpUrl = DUMP_URL + responseNode.get("key").asText();
+        sender.sendMessage("We've made a dump with useful information, report your issue and provide this url: " + ChatColor.DARK_AQUA + uploadedDumpUrl);
+        if (!sender.isConsole()) {
+            connector.getLogger().info(sender.getName() + " created a GeyserDump at " + uploadedDumpUrl);
+        }
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java
index 576e5ed0d..0e203231a 100644
--- a/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java
+++ b/connector/src/main/java/org/geysermc/connector/configuration/GeyserJacksonConfiguration.java
@@ -30,6 +30,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Getter;
 import lombok.Setter;
+import org.geysermc.common.serializer.AsteriskSerializer;
 
 import java.nio.file.Path;
 import java.util.Map;
@@ -111,16 +112,16 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
         @Setter
         private int port;
 
-        private String motd1;
-        private String motd2;
-
         @JsonProperty("auth-type")
         private String authType;
     }
 
     @Getter
     public static class UserAuthenticationInfo implements IUserAuthenticationInfo {
+        @AsteriskSerializer.Asterisk()
         private String email;
+
+        @AsteriskSerializer.Asterisk()
         private String password;
     }
 
diff --git a/connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java b/connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java
new file mode 100644
index 000000000..dbcfba819
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/dump/BootstrapDumpInfo.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *  THE SOFTWARE.
+ *
+ *  @author GeyserMC
+ *  @link https://github.com/GeyserMC/Geyser
+ *
+ */
+
+package org.geysermc.connector.dump;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.geysermc.common.PlatformType;
+import org.geysermc.connector.GeyserConnector;
+
+import java.util.List;
+
+@Getter
+public class BootstrapDumpInfo {
+
+    private PlatformType platform;
+
+    public BootstrapDumpInfo() {
+        this.platform = GeyserConnector.getInstance().getPlatformType();
+    }
+
+    @Getter
+    @AllArgsConstructor
+    public class PluginInfo {
+
+        public boolean enabled;
+        public String name;
+        public String version;
+        public String main;
+        public List<String> authors;
+    }
+
+    @Getter
+    @AllArgsConstructor
+    public class ListenerInfo {
+
+        public String ip;
+        public int port;
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/dump/DumpInfo.java b/connector/src/main/java/org/geysermc/connector/dump/DumpInfo.java
new file mode 100644
index 000000000..6d4b83db8
--- /dev/null
+++ b/connector/src/main/java/org/geysermc/connector/dump/DumpInfo.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to deal
+ *  in the Software without restriction, including without limitation the rights
+ *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ *  copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ *  THE SOFTWARE.
+ *
+ *  @author GeyserMC
+ *  @link https://github.com/GeyserMC/Geyser
+ *
+ */
+
+package org.geysermc.connector.dump;
+
+import com.github.steveice10.mc.protocol.MinecraftConstants;
+import lombok.Getter;
+import org.geysermc.connector.GeyserConnector;
+import org.geysermc.connector.configuration.GeyserConfiguration;
+import org.geysermc.connector.utils.DockerCheck;
+import org.geysermc.connector.utils.FileUtils;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Properties;
+
+@Getter
+public class DumpInfo {
+
+    private final DumpInfo.VersionInfo versionInfo;
+    private Properties gitInfo;
+    private final GeyserConfiguration config;
+    private final BootstrapDumpInfo bootstrapInfo;
+
+    public DumpInfo() {
+        try {
+            this.gitInfo = new Properties();
+            this.gitInfo.load(FileUtils.getResource("git.properties"));
+        } catch (IOException ignored) { }
+
+        this.config = GeyserConnector.getInstance().getConfig();
+
+        this.versionInfo = new DumpInfo.VersionInfo();
+        this.bootstrapInfo = GeyserConnector.getInstance().getBootstrap().getDumpInfo();
+    }
+
+    @Getter
+    public class VersionInfo {
+
+        private final String name;
+        private final String version;
+        private final String javaVersion;
+        private final String architecture;
+        private final String operatingSystem;
+
+        private final NetworkInfo network;
+        private final MCInfo mcInfo;
+
+        VersionInfo() {
+            this.name = GeyserConnector.NAME;
+            this.version = GeyserConnector.VERSION;
+            this.javaVersion = System.getProperty("java.version");
+            this.architecture = System.getProperty("os.arch"); // Usually gives Java architecture but still may be helpful.
+            this.operatingSystem = System.getProperty("os.name");
+
+            this.network = new NetworkInfo();
+            this.mcInfo = new MCInfo();
+        }
+    }
+
+    @Getter
+    public static class NetworkInfo {
+
+        private String internalIP;
+        private final boolean dockerCheck;
+
+        NetworkInfo() {
+            try {
+                // This is the most reliable for getting the main local IP
+                Socket socket = new Socket();
+                socket.connect(new InetSocketAddress("geysermc.org", 80));
+                this.internalIP = socket.getLocalAddress().getHostAddress();
+            } catch (IOException e1) {
+                try {
+                    // Fallback to the normal way of getting the local IP
+                    this.internalIP = InetAddress.getLocalHost().getHostAddress();
+                } catch (UnknownHostException ignored) { }
+            }
+
+            this.dockerCheck = DockerCheck.checkBasic();
+        }
+    }
+
+    @Getter
+    public static class MCInfo {
+
+        private final String bedrockVersion;
+        private final int bedrockProtocol;
+        private final String javaVersion;
+        private final int javaProtocol;
+
+        MCInfo() {
+            this.bedrockVersion = GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion();
+            this.bedrockProtocol = GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion();
+            this.javaVersion = MinecraftConstants.GAME_VERSION;
+            this.javaProtocol = MinecraftConstants.PROTOCOL_VERSION;
+        }
+    }
+}
diff --git a/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java b/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java
index 0a5a2278c..09c78da92 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/DockerCheck.java
@@ -55,4 +55,19 @@ public class DockerCheck {
             }
         } catch (Exception e) { } // Ignore any errors, inc ip failed to fetch, process could not run or access denied
     }
+
+    public static boolean checkBasic() {
+        try {
+            String OS = System.getProperty("os.name").toLowerCase();
+            if (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0) {
+                String output = new String(Files.readAllBytes(Paths.get("/proc/1/cgroup")));
+
+                if (output.contains("docker")) {
+                    return true;
+                }
+            }
+        } catch (Exception ignored) { } // Ignore any errors, inc ip failed to fetch, process could not run or access denied
+
+        return false;
+    }
 }
diff --git a/connector/src/main/java/org/geysermc/connector/utils/WebUtils.java b/connector/src/main/java/org/geysermc/connector/utils/WebUtils.java
index 50ab76d0b..7a1a0215f 100644
--- a/connector/src/main/java/org/geysermc/connector/utils/WebUtils.java
+++ b/connector/src/main/java/org/geysermc/connector/utils/WebUtils.java
@@ -25,11 +25,10 @@
 
 package org.geysermc.connector.utils;
 
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
+import java.io.*;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
@@ -81,4 +80,31 @@ public class WebUtils {
             throw new AssertionError("Unable to download and save file: " + fileLocation + " (" + reqURL + ")", e);
         }
     }
+
+    public static String post(String reqURL, String postContent) throws IOException {
+        URL url = null;
+        url = new URL(reqURL);
+        HttpURLConnection con = (HttpURLConnection) url.openConnection();
+        con.setRequestMethod("POST");
+        con.setRequestProperty("Content-Type", "text/plain");
+        con.setDoOutput(true);
+
+        OutputStream out = con.getOutputStream();
+        out.write(postContent.getBytes(StandardCharsets.UTF_8));
+        out.close();
+
+        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
+        String inputLine;
+        StringBuffer content = new StringBuffer();
+
+        while ((inputLine = in.readLine()) != null) {
+            content.append(inputLine);
+            content.append("\n");
+        }
+
+        in.close();
+        con.disconnect();
+
+        return content.toString();
+    }
 }