Compare commits

..

3 Commits

Author SHA1 Message Date
games647
4f3c8adc27 Comment out potential debug code 2022-02-07 17:50:02 +01:00
games647
d4a424f297 Fix TCPShield compat by using raw address for sessions
TCPShield overwrites the IP address during connection. ProtocolLib
doesn't notice this change, because it uses the end-to-end connection
which is the proxy IP. This causes getAddress calls during Spigot play
state and ProtocolLib auth state not match and then have conflicting
session ids.

A solution is also to hold onto the temporary player object. However
since we don't get a notification for a disconnect, holding it will
prevent to get GCed until the timeout occurs (1 minute).

Fixes #595

diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java
index ca8a927..bc03268 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/FastLoginBukkit.java
@@ -25,6 +25,7 @@
  */
 package com.github.games647.fastlogin.bukkit;

+import com.destroystokyo.paper.event.player.PlayerHandshakeEvent;
 import com.github.games647.fastlogin.bukkit.command.CrackedCommand;
 import com.github.games647.fastlogin.bukkit.command.PremiumCommand;
 import com.github.games647.fastlogin.bukkit.listener.ConnectionListener;
@@ -55,6 +56,8 @@ import java.util.concurrent.ConcurrentMap;
 import org.bukkit.Bukkit;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
 import org.bukkit.plugin.PluginManager;
 import org.bukkit.plugin.java.JavaPlugin;
 import org.geysermc.floodgate.api.FloodgateApi;
@@ -104,6 +107,15 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
         bungeeManager = new BungeeManager(this);
         bungeeManager.initialize();

+        getServer().getPluginManager().registerEvents(new Listener() {
+
+            @EventHandler
+            void onHandshake(PlayerHandshakeEvent handshakeEvent) {
+                handshakeEvent.setCancelled(false);
+                handshakeEvent.setSocketAddressHostname("192.168.0.1");
+            }
+        }, this);
+
         PluginManager pluginManager = getServer().getPluginManager();
         if (bungeeManager.isEnabled()) {
             markInitialized();
@@ -290,16 +302,17 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
         receiver.sendMessage(message);
     }

-	/**
-	 * Checks if a plugin is installed on the server
-	 * @param name the name of the plugin
-	 * @return true if the plugin is installed
-	 */
-	@Override
-	public boolean isPluginInstalled(String name) {
-	    // the plugin may be enabled after FastLogin, so isPluginEnabled() won't work here
-	    return Bukkit.getServer().getPluginManager().getPlugin(name) != null;
-	}
+    /**
+     * Checks if a plugin is installed on the server
+     *
+     * @param name the name of the plugin
+     * @return true if the plugin is installed
+     */
+    @Override
+    public boolean isPluginInstalled(String name) {
+        // the plugin may be enabled after FastLogin, so isPluginEnabled() won't work here
+        return Bukkit.getServer().getPluginManager().getPlugin(name) != null;
+    }

     public FloodgateService getFloodgateService() {
         return floodgateService;
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/AuthMeHook.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/AuthMeHook.java
index 10a396f..01cb4b9 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/AuthMeHook.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/hook/AuthMeHook.java
@@ -28,18 +28,20 @@ package com.github.games647.fastlogin.bukkit.hook;
 import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
 import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
 import com.github.games647.fastlogin.core.hooks.AuthPlugin;
+
 import fr.xephi.authme.api.v3.AuthMeApi;
 import fr.xephi.authme.events.RestoreSessionEvent;
 import fr.xephi.authme.process.Management;
 import fr.xephi.authme.process.register.executors.ApiPasswordRegisterParams;
 import fr.xephi.authme.process.register.executors.RegistrationMethod;
+
+import java.lang.reflect.Field;
+
 import org.bukkit.entity.Player;
 import org.bukkit.event.EventHandler;
 import org.bukkit.event.EventPriority;
 import org.bukkit.event.Listener;

-import java.lang.reflect.Field;
-
 /**
  * GitHub: https://github.com/Xephi/AuthMeReloaded/
  * <p>
@@ -75,7 +77,7 @@ public class AuthMeHook implements AuthPlugin<Player>, Listener {
     public void onSessionRestore(RestoreSessionEvent restoreSessionEvent) {
         Player player = restoreSessionEvent.getPlayer();

-        BukkitLoginSession session = plugin.getSession(player.getAddress());
+        BukkitLoginSession session = plugin.getSession(player.spigot().getRawAddress());
         if (session != null && session.isVerified()) {
             restoreSessionEvent.setCancelled(true);
         }
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeListener.java
index 2378450..856aa9a 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BungeeListener.java
@@ -127,7 +127,7 @@ public class BungeeListener implements PluginMessageListener {

     private void startLoginTaskIfReady(Player player, BukkitLoginSession session) {
         session.setVerified(true);
-        plugin.putSession(player.getAddress(), session);
+        plugin.putSession(player.spigot().getRawAddress(), session);

         // only start a new login task if the join event fired earlier. This event then didn't
         boolean result = plugin.getBungeeManager().didJoinEventFired(player);
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ConnectionListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ConnectionListener.java
index 05c9a18..d7c1ef1 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ConnectionListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/ConnectionListener.java
@@ -80,7 +80,7 @@ public class ConnectionListener implements Listener {
         // session exists so the player is ready for force login
         // cases: Paper (firing BungeeCord message before PlayerJoinEvent) or not running BungeeCord and already
         // having the login session from the login process
-        BukkitLoginSession session = plugin.getSession(player.getAddress());
+        BukkitLoginSession session = plugin.getSession(player.spigot().getRawAddress());

         if (session == null) {
             // Floodgate players usually don't have a session at this point
@@ -95,7 +95,7 @@ public class ConnectionListener implements Listener {
                 }
             }

-            String sessionId = plugin.getSessionId(player.getAddress());
+            String sessionId = plugin.getSessionId(player.spigot().getRawAddress());
             plugin.getLog().info("No on-going login session for player: {} with ID {}", player, sessionId);
         } else {
             Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player, session);
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolLoginSource.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolLoginSource.java
index 2e98178..0e182b4 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolLoginSource.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolLoginSource.java
@@ -51,7 +51,7 @@ public class ProtocolLoginSource implements LoginSource {

     @Override
     public InetSocketAddress getAddress() {
-        return loginStartEvent.getAddress();
+        return loginStartEvent.getConnection().getRawAddress();
     }

     public PlayerLoginStartEvent getLoginStartEvent() {
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java
index 8ce23da..6fa5cbe 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/protocolsupport/ProtocolSupportListener.java
@@ -70,7 +70,7 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
         }

         String username = loginStartEvent.getConnection().getProfile().getName();
-        InetSocketAddress address = loginStartEvent.getAddress();
+        InetSocketAddress address = loginStartEvent.getConnection().getRawAddress();

         //remove old data every time on a new login in order to keep the session only for one person
         plugin.removeSession(address);
@@ -81,13 +81,14 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende

     @EventHandler
     public void onConnectionClosed(ConnectionCloseEvent closeEvent) {
-        InetSocketAddress address = closeEvent.getConnection().getAddress();
+        InetSocketAddress address = closeEvent.getConnection().getRawAddress();
         plugin.removeSession(address);
     }

     @EventHandler
     public void onPropertiesResolve(PlayerProfileCompleteEvent profileCompleteEvent) {
-        InetSocketAddress address = profileCompleteEvent.getAddress();
+        InetSocketAddress address = profileCompleteEvent.getConnection().getRawAddress();
+
         BukkitLoginSession session = plugin.getSession(address);

         if (session != null && profileCompleteEvent.getConnection().getProfile().isOnlineMode()) {
2022-02-07 17:48:22 +01:00
games647
21347f705a Use the address field for verify task 2022-02-07 17:44:41 +01:00
18 changed files with 44 additions and 847 deletions

View File

@@ -353,47 +353,5 @@
<optional>true</optional>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.16.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mockserver</artifactId>
<version>1.16.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-client-java</artifactId>
<version>5.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.steveice10</groupId>
<artifactId>mcprotocollib</artifactId>
<version>1.18-2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>authlib</artifactId>
<version>3.2.38</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -25,6 +25,7 @@
*/
package com.github.games647.fastlogin.bukkit;
import com.destroystokyo.paper.event.player.PlayerHandshakeEvent;
import com.github.games647.fastlogin.bukkit.command.CrackedCommand;
import com.github.games647.fastlogin.bukkit.command.PremiumCommand;
import com.github.games647.fastlogin.bukkit.listener.ConnectionListener;
@@ -55,6 +56,8 @@ import java.util.concurrent.ConcurrentMap;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.geysermc.floodgate.api.FloodgateApi;
@@ -104,6 +107,15 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
bungeeManager = new BungeeManager(this);
bungeeManager.initialize();
// getServer().getPluginManager().registerEvents(new Listener() {
//
// @EventHandler
// void onHandshake(PlayerHandshakeEvent handshakeEvent) {
// handshakeEvent.setCancelled(false);
// handshakeEvent.setSocketAddressHostname("192.168.0.1");
// }
// }, this);
PluginManager pluginManager = getServer().getPluginManager();
if (bungeeManager.isEnabled()) {
markInitialized();
@@ -290,16 +302,17 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
receiver.sendMessage(message);
}
/**
* Checks if a plugin is installed on the server
* @param name the name of the plugin
* @return true if the plugin is installed
*/
@Override
public boolean isPluginInstalled(String name) {
// the plugin may be enabled after FastLogin, so isPluginEnabled() won't work here
return Bukkit.getServer().getPluginManager().getPlugin(name) != null;
}
/**
* Checks if a plugin is installed on the server
*
* @param name the name of the plugin
* @return true if the plugin is installed
*/
@Override
public boolean isPluginInstalled(String name) {
// the plugin may be enabled after FastLogin, so isPluginEnabled() won't work here
return Bukkit.getServer().getPluginManager().getPlugin(name) != null;
}
public FloodgateService getFloodgateService() {
return floodgateService;

View File

@@ -28,18 +28,20 @@ package com.github.games647.fastlogin.bukkit.hook;
import com.github.games647.fastlogin.bukkit.BukkitLoginSession;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
import fr.xephi.authme.api.v3.AuthMeApi;
import fr.xephi.authme.events.RestoreSessionEvent;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.process.register.executors.ApiPasswordRegisterParams;
import fr.xephi.authme.process.register.executors.RegistrationMethod;
import java.lang.reflect.Field;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import java.lang.reflect.Field;
/**
* GitHub: https://github.com/Xephi/AuthMeReloaded/
* <p>
@@ -75,7 +77,7 @@ public class AuthMeHook implements AuthPlugin<Player>, Listener {
public void onSessionRestore(RestoreSessionEvent restoreSessionEvent) {
Player player = restoreSessionEvent.getPlayer();
BukkitLoginSession session = plugin.getSession(player.getAddress());
BukkitLoginSession session = plugin.getSession(player.spigot().getRawAddress());
if (session != null && session.isVerified()) {
restoreSessionEvent.setCancelled(true);
}

View File

@@ -127,7 +127,7 @@ public class BungeeListener implements PluginMessageListener {
private void startLoginTaskIfReady(Player player, BukkitLoginSession session) {
session.setVerified(true);
plugin.putSession(player.getAddress(), session);
plugin.putSession(player.spigot().getRawAddress(), session);
// only start a new login task if the join event fired earlier. This event then didn't
boolean result = plugin.getBungeeManager().didJoinEventFired(player);

View File

@@ -80,7 +80,7 @@ public class ConnectionListener implements Listener {
// session exists so the player is ready for force login
// cases: Paper (firing BungeeCord message before PlayerJoinEvent) or not running BungeeCord and already
// having the login session from the login process
BukkitLoginSession session = plugin.getSession(player.getAddress());
BukkitLoginSession session = plugin.getSession(player.spigot().getRawAddress());
if (session == null) {
// Floodgate players usually don't have a session at this point
@@ -95,7 +95,7 @@ public class ConnectionListener implements Listener {
}
}
String sessionId = plugin.getSessionId(player.getAddress());
String sessionId = plugin.getSessionId(player.spigot().getRawAddress());
plugin.getLog().info("No on-going login session for player: {} with ID {}", player, sessionId);
} else {
Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player, session);

View File

@@ -209,7 +209,7 @@ public class VerifyResponseTask implements Runnable {
}
private boolean enableEncryption(SecretKey loginKey) throws IllegalArgumentException {
plugin.getLog().info("Enabling onlinemode encryption for {}", player.getName());
plugin.getLog().info("Enabling onlinemode encryption for {}", player.getAddress());
// Initialize method reflections
if (encryptMethod == null) {
Class<?> networkManagerClass = MinecraftReflection.getNetworkManagerClass();

View File

@@ -51,7 +51,7 @@ public class ProtocolLoginSource implements LoginSource {
@Override
public InetSocketAddress getAddress() {
return loginStartEvent.getAddress();
return loginStartEvent.getConnection().getRawAddress();
}
public PlayerLoginStartEvent getLoginStartEvent() {

View File

@@ -70,7 +70,7 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
}
String username = loginStartEvent.getConnection().getProfile().getName();
InetSocketAddress address = loginStartEvent.getAddress();
InetSocketAddress address = loginStartEvent.getConnection().getRawAddress();
//remove old data every time on a new login in order to keep the session only for one person
plugin.removeSession(address);
@@ -81,13 +81,14 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
@EventHandler
public void onConnectionClosed(ConnectionCloseEvent closeEvent) {
InetSocketAddress address = closeEvent.getConnection().getAddress();
InetSocketAddress address = closeEvent.getConnection().getRawAddress();
plugin.removeSession(address);
}
@EventHandler
public void onPropertiesResolve(PlayerProfileCompleteEvent profileCompleteEvent) {
InetSocketAddress address = profileCompleteEvent.getAddress();
InetSocketAddress address = profileCompleteEvent.getConnection().getRawAddress();
BukkitLoginSession session = plugin.getSession(address);
if (session != null && profileCompleteEvent.getConnection().getProfile().isOnlineMode()) {

View File

@@ -1,218 +0,0 @@
package integration;
import com.github.steveice10.mc.protocol.MinecraftProtocol;
import com.github.steveice10.packetlib.Session;
import com.github.steveice10.packetlib.event.session.DisconnectedEvent;
import com.github.steveice10.packetlib.event.session.SessionAdapter;
import com.github.steveice10.packetlib.packet.Packet;
import com.github.steveice10.packetlib.tcp.TcpClientSession;
import com.google.common.io.CharStreams;
import com.mojang.authlib.EnvironmentParser;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.mockserver.client.MockServerClient;
import org.mockserver.model.HttpRequest;
import org.mockserver.verify.VerificationTimes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.MockServerContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
// Warning name is sensitive to the surefire plugin
public class LoginIT {
private static final Logger LOG = LoggerFactory.getLogger(LoginIT.class);
private static final String API_TAG = "mockserver-5.11.2";
private static final String API_IMAGE_NAME = "mockserver/mockserver";
private static final String API_IMAGE = API_IMAGE_NAME + ':' + API_TAG;
@Rule
public MockServerContainer mockServer = new MockServerContainer(DockerImageName.parse(API_IMAGE))
.withReuse(true);
private static final String SERVER_TAG = "1.18.1@sha256:dd3c8d212de585ec73113a0c0c73ac755ec1ff53e65bb09089061584fac02053";
private static final String SERVER_IMAGE_NAME = "ghcr.io/games647/paperclip";
private static final String SERVER_IMAGE = SERVER_IMAGE_NAME + ':' + SERVER_TAG;
private static final String HOME_FOLDER = "/home/nonroot/";
private static final long MINECRAFT_MAX_MEMORY = 1024 * 1024 * 1024L;
@Rule
public GenericContainer<?> minecraftServer = new GenericContainer<>(DockerImageName.parse(SERVER_IMAGE))
.withEnv("JDK_JAVA_OPTIONS", buildJVMFlags())
.withExposedPorts(25565)
// use server settings that use minimal minecraft log to quickly ramp up the server
.withCopyFileToContainer(MountableFile.forClasspathResource("server.properties"), HOME_FOLDER + "server.properties")
.withCopyFileToContainer(MountableFile.forClasspathResource("bukkit.yml"), HOME_FOLDER + "bukkit.yml")
.withCopyFileToContainer(MountableFile.forClasspathResource("spigot.yml"), HOME_FOLDER + "spigot.yml")
// create folders that are volatile
.withTmpFs(getTempFS())
// Done (XXXXs)! For help, type "help"
.waitingFor(
Wait.forLogMessage(".*For help, type \"help\"*\\n", 1)
)
.withReuse(true)
.withLogConsumer(new Slf4jLogConsumer(LOG))
.withCreateContainerCmdModifier(cmd -> cmd.getHostConfig().withMemory(MINECRAFT_MAX_MEMORY));
private Map<String, String> getTempFS() {
Map<String, String> tmpfs = new HashMap<>();
tmpfs.put(HOME_FOLDER + "world", "rw,noexec,nosuid,nodev");
tmpfs.put(HOME_FOLDER + "logs", "rw,noexec,nosuid,nodev");
return tmpfs;
}
private String buildJVMFlags() {
Map<String, String> systemProperties = new HashMap<>();
systemProperties.put("com.mojang.eula.agree", Boolean.toString(true));
// set the Yggdrasil hosts that will also be used by the vanilla server
systemProperties.put(EnvironmentParser.PROP_ACCOUNT_HOST, getProxyHost());
systemProperties.put(EnvironmentParser.PROP_SESSION_HOST, getProxyHost());
return systemProperties.entrySet().stream()
.map(entry -> "-D" + entry.getKey() + '=' + entry.getValue())
.collect(Collectors.joining(" ")) + " -client";
}
@Test
public void checkRunning() throws Exception {
assertThat(minecraftServer.isRunning(), is(true));
String host = minecraftServer.getHost();
int port = minecraftServer.getMappedPort(25565);
Session clientSession = new TcpClientSession(host, port, new MinecraftProtocol());
try {
CompletableFuture<Boolean> connectionResult = new CompletableFuture<>();
clientSession.addListener(new SessionAdapter() {
@Override
public void packetReceived(Session session, Packet packet) {
LOG.info("Client received: {}", packet.getClass());
connectionResult.complete(true);
}
@Override
public void disconnected(DisconnectedEvent event) {
connectionResult.complete(false);
}
});
clientSession.connect();
assertThat(connectionResult.get(2, TimeUnit.SECONDS), is(true));
} finally {
clientSession.disconnect("Status test complete.");
}
}
private String getProxyHost() {
return String.format("https://%s:%d", mockServer.getHost(), mockServer.getServerPort());
}
@Test
@Ignore
public void autoRegisterNewUser() throws Exception {
assertThat(mockServer.isRunning(), is(true));
try (MockServerClient client = new MockServerClient(mockServer.getHost(), mockServer.getServerPort())) {
HttpRequest profileReq = request("/users/profiles/minecraft/" + "username");
HttpRequest hasJoinedReq = request()
.withPath("/session/minecraft/hasJoined")
.withQueryStringParameter("username", "")
.withQueryStringParameter("serverId", "")
.withQueryStringParameter("ip", "");
// check call network request times
client.verify(profileReq, VerificationTimes.once());
client.verify(hasJoinedReq, VerificationTimes.once());
// Verify order
client.verify(profileReq, hasJoinedReq);
client
.when(request()
.withPath("/users/profiles/minecraft/" + "username"))
.respond(response()
.withBody("bla"));
client
.when(hasJoinedReq)
.respond(response()
.withBody("Test"));
URLConnection urlConnection = new URL(mockServer.getEndpoint() + "/users/profiles/minecraft/username").openConnection();
String out = CharStreams.toString(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8));
LOG.info("OUTPUT: {}", out);
}
}
@Test
@Ignore
public void failedJoinedVerification() {
// has joined fails
}
@Test
@Ignore
public void offlineLoginNewUserDisabledRegister() {
// auto register disabled, always offline login for new users
}
@Test
@Ignore
public void offlineLoginNewUser() {
// auto register enabled, but no paid account
}
@Test
@Ignore
public void autoLoginRegistered() {
// registered premium user and paid account login in
}
@Test
@Ignore
public void failedLoginPremiumRegistered() {
// registered premium, but tried offline login
}
@Test
@Ignore
public void offlineLoginRegistered() {
// assume registered user marked as offline - tried to login
}
@Test
@Ignore
public void alreadyOnlineDuplicateOwner() {
}
@Test
@Ignore
public void alreadyOnlineDuplicateCracked() {
}
}

View File

@@ -1,29 +0,0 @@
settings:
allow-end: false
warn-on-overload: true
permissions-file: permissions.yml
update-folder: update
plugin-profiling: false
connection-throttle: 4000
query-plugins: false
deprecated-verbose: default
shutdown-message: Server closed
minimum-api: none
spawn-limits:
monsters: 70
animals: 10
water-animals: 5
water-ambient: 20
water-underground-creature: 5
ambient: 15
chunk-gc:
period-in-ticks: 600
ticks-per:
animal-spawns: 400
monster-spawns: 1
water-spawns: 1
water-ambient-spawns: 1
water-underground-creature-spawns: 1
ambient-spawns: 1
autosave: 6000
aliases: now-in-commands.yml

View File

@@ -1,14 +0,0 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
<logger name="org.testcontainers" level="INFO"/>
<logger name="com.github.dockerjava" level="WARN"/>
</configuration>

View File

@@ -1,292 +0,0 @@
# This is the main configuration file for Paper.
# As you can see, there's tons to configure. Some options may impact gameplay, so use
# with caution, and make sure you know what each option does before configuring.
#
# If you need help with the configuration or have any questions related to Paper,
# join us in our Discord or IRC channel.
#
# Discord: https://discord.gg/papermc
# IRC: #paper @ irc.esper.net ( https://webchat.esper.net/?channels=paper )
# Website: https://papermc.io/
# Docs: https://paper.readthedocs.org/
verbose: false
messages:
kick:
authentication-servers-down: ''
connection-throttle: Connection throttled! Please wait before reconnecting.
flying-player: Flying is not enabled on this server
flying-vehicle: Flying is not enabled on this server
no-permission: '&cI''m sorry, but you do not have permission to perform this command.
Please contact the server administrators if you believe that this is in error.'
timings:
enabled: false
verbose: true
url: https://timings.aikar.co/
server-name-privacy: false
hidden-config-entries: []
history-interval: 300
history-length: 3600
server-name: Unknown Server
config-version: 24
settings:
max-joins-per-tick: 3
track-plugin-scoreboards: false
fix-entity-position-desync: true
use-display-name-in-quit-message: false
load-permissions-yml-before-plugins: true
region-file-cache-size: 256
enable-player-collisions: false
save-empty-scoreboard-teams: false
bungee-online-mode: true
incoming-packet-spam-threshold: 300
use-alternative-luck-formula: false
velocity-support:
enabled: false
online-mode: false
secret: ''
console-has-all-permissions: false
player-auto-save-rate: -1
max-player-auto-save-per-tick: -1
fix-target-selector-tag-completion: true
lag-compensate-block-breaking: true
time-command-affects-all-worlds: false
log-player-ip-addresses: false
console:
enable-brigadier-highlighting: false
enable-brigadier-completions: false
suggest-player-names-when-null-tab-completions: false
watchdog:
early-warning-every: 5000
early-warning-delay: 10000
spam-limiter:
tab-spam-increment: 1
tab-spam-limit: 500
recipe-spam-increment: 1
recipe-spam-limit: 20
book-size:
page-max: 2560
total-multiplier: 0.98
loggers:
deobfuscate-stacktraces: true
item-validation:
display-name: 8192
loc-name: 8192
lore-line: 8192
book:
title: 8192
author: 8192
page: 16384
send-full-pos-for-hard-colliding-entities: true
async-chunks:
threads: -1
unsupported-settings:
allow-permanent-block-break-exploits: false
allow-piston-duplication: false
perform-username-validation: true
allow-headless-pistons: false
allow-permanent-block-break-exploits-readme: This setting controls if players
should be able to break bedrock, end portals and other intended to be permanent
blocks.
allow-piston-duplication-readme: This setting controls if player should be able
to use TNT duplication, but this also allows duplicating carpet, rails and potentially
other items
allow-headless-pistons-readme: This setting controls if players should be able
to create headless pistons.
packet-limiter:
kick-message: '&cSent too many packets'
limits: []
world-settings:
default:
delay-chunk-unloads-by: 10s
disable-teleportation-suffocation-check: true
generator-settings:
flat-bedrock: true
piglins-guard-chests: true
should-remove-dragon: false
max-auto-save-chunks-per-tick: 24
baby-zombie-movement-modifier: 0.5
optimize-explosions: false
use-vanilla-world-scoreboard-name-coloring: false
game-mechanics:
scan-for-legacy-ender-dragon: true
fix-curing-zombie-villager-discount-exploit: true
disable-pillager-patrols: true
pillager-patrols:
spawn-chance: 0.2
spawn-delay:
per-player: false
ticks: 12000
start:
per-player: false
day: 5
disable-chest-cat-detection: true
nerf-pigmen-from-nether-portals: false
disable-player-crits: true
disable-sprint-interruption-on-attack: true
shield-blocking-delay: 5
disable-end-credits: true
disable-unloaded-chunk-enderpearl-exploit: true
disable-relative-projectile-velocity: true
disable-mob-spawner-spawn-egg-transformation: true
prevent-moving-into-unloaded-chunks: false
count-all-mobs-for-spawning: false
spawn-limits:
monster: -1
creature: -1
ambient: -1
axolotls: -1
underground_water_creature: -1
water_creature: -1
water_ambient: -1
ender-dragons-death-always-places-dragon-egg: false
experience-merge-max-value: -1
allow-using-signs-inside-spawn-protection: false
wandering-trader:
spawn-minute-length: 1200
spawn-day-length: 24000
spawn-chance-failure-increment: 25
spawn-chance-min: 25
spawn-chance-max: 75
door-breaking-difficulty:
zombie:
- HARD
vindicator:
- NORMAL
- HARD
max-growth-height:
cactus: 3
reeds: 3
bamboo:
max: 16
min: 11
fishing-time-range:
MinimumTicks: 100
MaximumTicks: 600
despawn-ranges: []
falling-block-height-nerf: 0
tnt-entity-height-nerf: 0
slime-spawn-height:
swamp-biome:
maximum: 70.0
minimum: 50.0
slime-chunk:
maximum: 40.0
frosted-ice:
enabled: true
delay:
min: 20
max: 40
lootables:
auto-replenish: false
restrict-player-reloot: true
reset-seed-on-fill: true
max-refills: -1
refresh-min: 12h
refresh-max: 2d
filter-nbt-data-from-spawn-eggs-and-related: true
max-entity-collisions: 8
disable-creeper-lingering-effect: true
duplicate-uuid-resolver: saferegen
duplicate-uuid-saferegen-delete-range: 32
hopper:
cooldown-when-full: true
disable-move-event: true
ignore-occluding-blocks: false
mob-effects:
undead-immune-to-certain-effects: true
spiders-immune-to-poison-effect: true
immune-to-wither-effect:
wither: true
wither-skeleton: true
update-pathfinding-on-block-update: true
phantoms-do-not-spawn-on-creative-players: true
phantoms-only-attack-insomniacs: true
mobs-can-always-pick-up-loot:
zombies: false
skeletons: false
map-item-frame-cursor-update-interval: 10
allow-player-cramming-damage: false
anticheat:
obfuscation:
items:
hide-itemmeta: false
hide-durability: false
monster-spawn-max-light-level: -1
water-over-lava-flow-speed: 5
grass-spread-tick-rate: 1
use-faster-eigencraft-redstone: false
nether-ceiling-void-damage-height: 0
only-players-collide: false
allow-vehicle-collisions: true
allow-non-player-entities-on-scoreboards: false
anti-xray:
enabled: false
engine-mode: 1
max-block-height: 64
update-radius: 2
lava-obscures: false
use-permission: false
hidden-blocks: []
replacement-blocks: []
keep-spawn-loaded: true
armor-stands-do-collision-entity-lookups: true
parrots-are-unaffected-by-player-movement: false
disable-explosion-knockback: true
portal-search-radius: 128
portal-create-radius: 16
portal-search-vanilla-dimension-scaling: true
fix-items-merging-through-walls: false
disable-thunder: true
skeleton-horse-thunder-spawn-chance: 0.01
disable-ice-and-snow: true
keep-spawn-loaded-range: 10
fix-climbing-bypassing-cramming-rule: false
container-update-tick-rate: 1
fixed-chunk-inhabited-time: -1
remove-corrupt-tile-entities: false
prevent-tnt-from-moving-in-water: false
iron-golems-can-spawn-in-air: false
max-leash-distance: 10.0
show-sign-click-command-failure-msgs-to-player: false
armor-stands-tick: true
non-player-arrow-despawn-rate: -1
creative-arrow-despawn-rate: -1
spawner-nerfed-mobs-should-jump: false
entities-target-with-follow-range: false
wateranimal-spawn-height:
maximum: default
minimum: default
zombies-target-turtle-eggs: true
zombie-villager-infection-chance: -1.0
unsupported-settings:
fix-invulnerable-end-crystal-exploit: true
all-chunks-are-slime-chunks: false
mob-spawner-tick-rate: 1
map-item-frame-cursor-limit: 128
per-player-mob-spawns: true
light-queue-size: 20
auto-save-interval: -1
enable-treasure-maps: false
treasure-maps-return-already-discovered: false
split-overstacked-loot: true
entity-per-chunk-save-limit:
experience_orb: -1
snowball: -1
ender_pearl: -1
arrow: -1
fireball: -1
small_fireball: -1
alt-item-despawn-rate:
enabled: false
items:
COBBLESTONE: 300
tick-rates:
sensor:
villager:
secondarypoisensor: 40
behavior:
villager:
validatenearbypoi: -1
feature-seeds:
generate-random-seeds-for-all: false

View File

@@ -1,50 +0,0 @@
#Minecraft server properties
enable-jmx-monitoring=false
rcon.port=25575
gamemode=creative
enable-command-block=false
enable-query=false
level-name=world
motd=Debug server
query.port=25565
pvp=false
difficulty=peaceful
network-compression-threshold=256
require-resource-pack=false
max-tick-time=60000
use-native-transport=true
max-players=2
online-mode=false
enable-status=true
allow-flight=false
broadcast-rcon-to-ops=true
view-distance=3
server-ip=
resource-pack-prompt=
allow-nether=false
server-port=25565
enable-rcon=false
sync-chunk-writes=false
op-permission-level=4
prevent-proxy-connections=false
hide-online-players=true
resource-pack=
entity-broadcast-range-percentage=10
simulation-distance=3
rcon.password=
player-idle-timeout=0
debug=true
force-gamemode=false
rate-limit=0
hardcore=false
white-list=false
broadcast-console-to-ops=false
spawn-npcs=false
spawn-animals=false
function-permission-level=2
text-filtering-config=
spawn-monsters=false
enforce-whitelist=false
resource-pack-sha1=
spawn-protection=0
max-world-size=1

View File

@@ -1,164 +0,0 @@
# This is the main configuration file for Spigot.
# As you can see, there's tons to configure. Some options may impact gameplay, so use
# with caution, and make sure you know what each option does before configuring.
# For a reference for any variable inside this file, check out the Spigot wiki at
# http://www.spigotmc.org/wiki/spigot-configuration/
#
# If you need help with the configuration or have any questions related to Spigot,
# join us at the Discord or drop by our forums and leave a post.
#
# Discord: https://www.spigotmc.org/go/discord
# Forums: http://www.spigotmc.org/
settings:
debug: true
bungeecord: false
sample-count: 0
player-shuffle: 0
user-cache-size: 1000
save-user-cache-on-stop-only: false
moved-wrongly-threshold: 0.0625
moved-too-quickly-multiplier: 10.0
timeout-time: 60
restart-on-crash: false
restart-script: ./start.sh
netty-threads: 1
attribute:
maxHealth:
max: 2048.0
movementSpeed:
max: 2048.0
attackDamage:
max: 2048.0
log-villager-deaths: false
log-named-deaths: false
messages:
whitelist: You are not whitelisted on this server!
unknown-command: Unknown command. Type "/help" for help.
server-full: The server is full!
outdated-client: Outdated client! Please use {0}
outdated-server: Outdated server! I'm still on {0}
restart: Server is restarting
advancements:
disable-saving: true
disabled: []
commands:
replace-commands: []
spam-exclusions: []
silent-commandblock-console: false
log: false
tab-complete: 0
send-namespaced: false
players:
disable-saving: true
world-settings:
default:
below-zero-generation-in-existing-chunks: true
verbose: false
merge-radius:
exp: 3.0
item: 2.5
growth:
cactus-modifier: 100
cane-modifier: 100
melon-modifier: 100
mushroom-modifier: 100
pumpkin-modifier: 100
sapling-modifier: 100
beetroot-modifier: 100
carrot-modifier: 100
potato-modifier: 100
wheat-modifier: 100
netherwart-modifier: 100
vine-modifier: 100
cocoa-modifier: 100
bamboo-modifier: 100
sweetberry-modifier: 100
kelp-modifier: 100
twistingvines-modifier: 100
weepingvines-modifier: 100
cavevines-modifier: 100
glowberry-modifier: 100
entity-activation-range:
animals: 32
monsters: 32
raiders: 48
misc: 16
water: 16
villagers: 32
flying-monsters: 32
wake-up-inactive:
animals-max-per-tick: 4
animals-every: 1200
animals-for: 100
monsters-max-per-tick: 8
monsters-every: 400
monsters-for: 100
villagers-max-per-tick: 4
villagers-every: 600
villagers-for: 100
flying-monsters-max-per-tick: 8
flying-monsters-every: 200
flying-monsters-for: 100
villagers-work-immunity-after: 100
villagers-work-immunity-for: 20
villagers-active-for-panic: true
tick-inactive-villagers: true
ignore-spectators: false
entity-tracking-range:
players: 48
animals: 48
monsters: 48
misc: 32
other: 64
ticks-per:
hopper-transfer: 8
hopper-check: 1
hopper-amount: 1
dragon-death-sound-radius: 0
seed-village: 10387312
seed-desert: 14357617
seed-igloo: 14357618
seed-jungle: 14357619
seed-swamp: 14357620
seed-monument: 10387313
seed-shipwreck: 165745295
seed-ocean: 14357621
seed-outpost: 165745296
seed-endcity: 10387313
seed-slime: 987234911
seed-bastion: 30084232
seed-fortress: 30084232
seed-mansion: 10387319
seed-fossil: 14357921
seed-portal: 34222645
seed-stronghold: default
hunger:
jump-walk-exhaustion: 0.05
jump-sprint-exhaustion: 0.2
combat-exhaustion: 0.1
regen-exhaustion: 6.0
swim-multiplier: 0.01
sprint-multiplier: 0.1
other-multiplier: 0.0
max-tnt-per-tick: 100
max-tick-time:
tile: 50
entity: 50
enable-zombie-pigmen-portal-spawns: true
item-despawn-rate: 6000
view-distance: default
simulation-distance: default
thunder-chance: 100000
wither-spawn-sound-radius: 0
arrow-despawn-rate: 1200
trident-despawn-rate: 1200
hanging-tick-frequency: 100
zombie-aggressive-towards-villager: true
nerf-spawner-mobs: false
mob-spawn-range: 8
end-portal-sound-radius: 0
config-version: 12
stats:
disable-saving: true
forced-stats: {}

View File

@@ -179,7 +179,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
<version>2.8.9</version>
</dependency>
</dependencies>
</project>

View File

@@ -231,7 +231,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
databaseConfig.setUsername(config.get("username", ""));
databaseConfig.setPassword(config.getString("password"));
storage = new MySQLStorage(this, driver, host, port, database, databaseConfig, useSSL);
storage = new MySQLStorage(this, host, port, database, databaseConfig, useSSL);
}
try {
@@ -250,8 +250,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
} catch (ClassNotFoundException notFoundEx) {
Logger log = plugin.getLog();
log.warn("This driver {} is not supported on this platform", className);
log.warn("Please choose either MySQL (Spigot, BungeeCord), SQLite (Spigot, Sponge) or " +
"MariaDB (Sponge, Velocity)", notFoundEx);
log.warn("Please choose MySQL (Spigot+BungeeCord), SQLite (Spigot+Sponge) or MariaDB (Sponge)", notFoundEx);
}
return false;

View File

@@ -5,22 +5,13 @@ import com.zaxxer.hikari.HikariConfig;
public class MySQLStorage extends SQLStorage {
public MySQLStorage(FastLoginCore<?, ?, ?> core, String driver, String host, int port, String database,
HikariConfig config,boolean useSSL) {
public MySQLStorage(FastLoginCore<?, ?, ?> core, String host, int port, String database, HikariConfig config,
boolean useSSL) {
super(core,
buildJDBCUrl(driver, host, port, database),
"mysql://" + host + ':' + port + '/' + database,
setParams(config, useSSL));
}
private static String buildJDBCUrl(String driver, String host, int port, String database) {
String protocol = "mysql";
if (driver.contains("mariadb")) {
protocol = "mariadb";
}
return protocol + "://" + host + ':' + port + '/' + database;
}
private static HikariConfig setParams(HikariConfig config, boolean useSSL) {
// Require SSL on the server if requested in config - this will also verify certificate
// Those values are deprecated in favor of sslMode

View File

@@ -129,7 +129,7 @@
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.0.3</version>
<version>2.7.5</version>
</dependency>
</dependencies>
</project>