mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-07-29 18:27:36 +02:00
Merge pull request #779 from Smart123s/feature/codeformatter
Add a code formatter
This commit is contained in:
@ -51,8 +51,8 @@ public class BukkitLoginSession extends LoginSession {
|
||||
|
||||
private SkinProperty skinProperty;
|
||||
|
||||
public BukkitLoginSession(String username, byte[] verifyToken, ClientPublicKey publicKey, boolean registered
|
||||
, StoredProfile profile) {
|
||||
public BukkitLoginSession(String username, byte[] verifyToken, ClientPublicKey publicKey, boolean registered,
|
||||
StoredProfile profile) {
|
||||
super(username, registered, profile);
|
||||
|
||||
this.clientPublicKey = publicKey;
|
||||
|
@ -33,6 +33,7 @@ import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -113,7 +114,9 @@ public class BungeeManager {
|
||||
Class<?> globalConfig = Class.forName("io.papermc.paper.configuration.GlobalConfiguration");
|
||||
Object global = globalConfig.getDeclaredMethod("get").invoke(null);
|
||||
Object proxiesConfiguration = global.getClass().getDeclaredField("proxies").get(global);
|
||||
Object velocityConfig = proxiesConfiguration.getClass().getDeclaredField("velocity").get(proxiesConfiguration);
|
||||
|
||||
Field velocitySectionField = proxiesConfiguration.getClass().getDeclaredField("velocity");
|
||||
Object velocityConfig = velocitySectionField.get(proxiesConfiguration);
|
||||
|
||||
return velocityConfig.getClass().getDeclaredField("enabled").getBoolean(velocityConfig);
|
||||
} catch (ClassNotFoundException classNotFoundException) {
|
||||
@ -128,7 +131,9 @@ public class BungeeManager {
|
||||
|
||||
private boolean detectProxy() {
|
||||
try {
|
||||
if (isProxySupported("org.spigotmc.SpigotConfig", "bungee")) return true;
|
||||
if (isProxySupported("org.spigotmc.SpigotConfig", "bungee")) {
|
||||
return true;
|
||||
}
|
||||
} catch (ClassNotFoundException classNotFoundException) {
|
||||
// leave stacktrace for class not found out
|
||||
plugin.getLog().warn("Cannot check for BungeeCord support: {}", classNotFoundException.getMessage());
|
||||
|
@ -120,18 +120,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
|
||||
ProtocolLibListener.register(this, core.getAntiBot(), core.getConfig().getBoolean("verifyClientKeys"));
|
||||
|
||||
if (isPluginInstalled("floodgate")) {
|
||||
if (getConfig().getBoolean("floodgatePrefixWorkaround")){
|
||||
ManualNameChange.register(this, floodgateService);
|
||||
logger.info("Floodgate prefix injection workaround has been enabled.");
|
||||
logger.info("If you have problems joining the server, try disabling it in the configuration.");
|
||||
} else {
|
||||
logger.warn("We have detected that you are running FastLogin alongside Floodgate and ProtocolLib.");
|
||||
logger.warn("Currently there is an issue with FastLogin that prevents Floodgate name prefixes from showing up "
|
||||
+ "when it is together used with ProtocolLib.");
|
||||
logger.warn("If you would like to use Floodgate name prefixes, you can enable an experimental workaround by changing "
|
||||
+ "the value 'floodgatePrefixWorkaround' to true in config.yml.");
|
||||
logger.warn("For more information visit https://github.com/games647/FastLogin/issues/493");
|
||||
}
|
||||
printFloodgateWarning();
|
||||
}
|
||||
|
||||
//if server is using paper - we need to set the skin at pre login anyway, so no need for this listener
|
||||
@ -167,6 +156,21 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
|
||||
dependencyWarnings();
|
||||
}
|
||||
|
||||
private void printFloodgateWarning() {
|
||||
if (getConfig().getBoolean("floodgatePrefixWorkaround")) {
|
||||
ManualNameChange.register(this, floodgateService);
|
||||
logger.info("Floodgate prefix injection workaround has been enabled.");
|
||||
logger.info("If you have problems joining the server, try disabling it in the configuration.");
|
||||
} else {
|
||||
logger.warn("We have detected that you are running FastLogin alongside Floodgate and ProtocolLib.");
|
||||
logger.warn("Currently there is an issue with FastLogin that prevents Floodgate name prefixes from "
|
||||
+ "showing up when it is together used with ProtocolLib.");
|
||||
logger.warn("If you would like to use Floodgate name prefixes, you can enable an experimental "
|
||||
+ "workaround by changing the value 'floodgatePrefixWorkaround' to true in config.yml.");
|
||||
logger.warn("For more information visit https://github.com/games647/FastLogin/issues/493");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean initializeFloodgate() {
|
||||
if (getServer().getPluginManager().getPlugin("Geyser-Spigot") != null) {
|
||||
geyserService = new GeyserService(GeyserImpl.getInstance(), core);
|
||||
@ -295,16 +299,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;
|
||||
@ -333,6 +338,6 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
|
||||
+ "Floodgate 2.0 from https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/dev%252F2.0/");
|
||||
logger.warn("Don't forget to update Geyser to a supported version as well from "
|
||||
+ "https://ci.opencollab.dev/job/GeyserMC/job/Geyser/job/floodgate-2.0/");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ public class CrackedCommand extends ToggleCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
String[] args) {
|
||||
if (args.length == 0) {
|
||||
onCrackedSelf(sender);
|
||||
} else {
|
||||
|
@ -49,7 +49,8 @@ public class PremiumCommand extends ToggleCommand {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
String[] args) {
|
||||
if (args.length == 0) {
|
||||
onPremiumSelf(sender);
|
||||
} else {
|
||||
|
@ -36,7 +36,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BukkitFastLoginAutoLoginEvent extends Event implements FastLoginAutoLoginEvent, Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
private final LoginSession session;
|
||||
private final StoredProfile profile;
|
||||
private boolean cancelled;
|
||||
@ -70,10 +70,10 @@ public class BukkitFastLoginAutoLoginEvent extends Event implements FastLoginAut
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return handlers;
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
return HANDLERS;
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BukkitFastLoginPreLoginEvent extends Event implements FastLoginPreLoginEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
private final String username;
|
||||
private final LoginSource source;
|
||||
private final StoredProfile profile;
|
||||
@ -65,10 +65,10 @@ public class BukkitFastLoginPreLoginEvent extends Event implements FastLoginPreL
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return handlers;
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
return HANDLERS;
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BukkitFastLoginPremiumToggleEvent extends Event implements FastLoginPremiumToggleEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
private final StoredProfile profile;
|
||||
private final PremiumToggleReason reason;
|
||||
|
||||
@ -56,10 +56,10 @@ public class BukkitFastLoginPremiumToggleEvent extends Event implements FastLogi
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return handlers;
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
return HANDLERS;
|
||||
}
|
||||
}
|
||||
|
@ -44,12 +44,12 @@ import org.bukkit.entity.Player;
|
||||
* <p>
|
||||
* Bukkit: <a href="https://dev.bukkit.org/bukkit-plugins/xauth/">...</a>
|
||||
*/
|
||||
public class xAuthHook implements AuthPlugin<Player> {
|
||||
public class XAuthHook implements AuthPlugin<Player> {
|
||||
|
||||
private final xAuth xAuthPlugin = xAuth.getPlugin();
|
||||
private final FastLoginBukkit plugin;
|
||||
|
||||
public xAuthHook(FastLoginBukkit plugin) {
|
||||
public XAuthHook(FastLoginBukkit plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
@ -97,8 +97,8 @@ public class ConnectionListener implements Listener {
|
||||
|
||||
String sessionId = plugin.getSessionId(player.getAddress());
|
||||
plugin.getLog().info("No on-going login session for player: {} with ID {}. ", player, sessionId);
|
||||
plugin.getLog().info("Setups using Minecraft proxies will start delayed " +
|
||||
"when the command from the proxy is received");
|
||||
plugin.getLog().info("Setups using Minecraft proxies will start delayed "
|
||||
+ "when the command from the proxy is received");
|
||||
} else {
|
||||
Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player, session);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, forceLoginTask);
|
||||
|
@ -34,7 +34,6 @@ import com.google.common.primitives.Longs;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
@ -63,20 +62,22 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
* Encryption and decryption minecraft util for connection between servers
|
||||
* and paid Minecraft account clients.
|
||||
*/
|
||||
class EncryptionUtil {
|
||||
final class EncryptionUtil {
|
||||
|
||||
public static final int VERIFY_TOKEN_LENGTH = 4;
|
||||
public static final String KEY_PAIR_ALGORITHM = "RSA";
|
||||
|
||||
private static final int RSA_LENGTH = 1_024;
|
||||
|
||||
private static final PublicKey mojangSessionKey;
|
||||
private static final PublicKey MOJANG_SESSION_KEY;
|
||||
private static final int LINE_LENGTH = 76;
|
||||
private static final Encoder KEY_ENCODER = Base64.getMimeEncoder(LINE_LENGTH, "\n".getBytes(StandardCharsets.UTF_8));
|
||||
private static final Encoder KEY_ENCODER = Base64.getMimeEncoder(
|
||||
LINE_LENGTH, "\n".getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
|
||||
static {
|
||||
try {
|
||||
mojangSessionKey = loadMojangSessionKey();
|
||||
MOJANG_SESSION_KEY = loadMojangSessionKey();
|
||||
} catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException ex) {
|
||||
throw new RuntimeException("Failed to load Mojang session key", ex);
|
||||
}
|
||||
@ -119,7 +120,7 @@ class EncryptionUtil {
|
||||
/**
|
||||
* Generate the server id based on client and server data.
|
||||
*
|
||||
* @param serverId session for the current login attempt
|
||||
* @param serverId session for the current login attempt
|
||||
* @param sharedSecret shared secret between the client and the server
|
||||
* @param publicKey public key of the server
|
||||
* @return the server id formatted as a hexadecimal string.
|
||||
@ -135,7 +136,6 @@ class EncryptionUtil {
|
||||
* @param privateKey private server key
|
||||
* @param sharedKey the encrypted shared key
|
||||
* @return shared secret key
|
||||
* @throws GeneralSecurityException if it fails to decrypt the data
|
||||
*/
|
||||
public static SecretKey decryptSharedKey(PrivateKey privateKey, byte[] sharedKey)
|
||||
throws NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException,
|
||||
@ -151,7 +151,7 @@ class EncryptionUtil {
|
||||
|
||||
Signature verifier = Signature.getInstance("SHA1withRSA");
|
||||
// key of the signer
|
||||
verifier.initVerify(mojangSessionKey);
|
||||
verifier.initVerify(MOJANG_SESSION_KEY);
|
||||
verifier.update(toSignable(clientKey).getBytes(StandardCharsets.US_ASCII));
|
||||
return verifier.verify(clientKey.signature());
|
||||
}
|
||||
|
@ -88,8 +88,8 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
|
||||
//Minecraft server implementation
|
||||
//https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/LoginListener.java#L161
|
||||
@Override
|
||||
public void requestPremiumLogin(ProtocolLibLoginSource source, StoredProfile profile
|
||||
, String username, boolean registered) {
|
||||
public void requestPremiumLogin(ProtocolLibLoginSource source, StoredProfile profile,
|
||||
String username, boolean registered) {
|
||||
try {
|
||||
source.enableOnlinemode();
|
||||
} catch (Exception ex) {
|
||||
|
@ -147,13 +147,16 @@ public class ProtocolLibListener extends PacketAdapter {
|
||||
|
||||
BukkitLoginSession session = plugin.getSession(sender.getAddress());
|
||||
if (session == null) {
|
||||
plugin.getLog().warn("GameProfile {} tried to send encryption response at invalid state", sender.getAddress());
|
||||
plugin.getLog().warn("Profile {} tried to send encryption response at invalid state", sender.getAddress());
|
||||
sender.kickPlayer(plugin.getCore().getMessage("invalid-request"));
|
||||
} else {
|
||||
byte[] expectedVerifyToken = session.getVerifyToken();
|
||||
if (verifyNonce(sender, packetEvent.getPacket(), session.getClientPublicKey(), expectedVerifyToken)) {
|
||||
packetEvent.getAsyncMarker().incrementProcessingDelay();
|
||||
Runnable verifyTask = new VerifyResponseTask(plugin, packetEvent, sender, session, sharedSecret, keyPair);
|
||||
|
||||
Runnable verifyTask = new VerifyResponseTask(
|
||||
plugin, packetEvent, sender, session, sharedSecret, keyPair
|
||||
);
|
||||
plugin.getScheduler().runAsync(verifyTask);
|
||||
} else {
|
||||
sender.kickPlayer(plugin.getCore().getMessage("invalid-verify-token"));
|
||||
@ -192,8 +195,8 @@ public class ProtocolLibListener extends PacketAdapter {
|
||||
byte[] nonce = packet.getByteArrays().read(1);
|
||||
return EncryptionUtil.verifyNonce(expectedToken, keyPair.getPrivate(), nonce);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | NoSuchPaddingException |
|
||||
IllegalBlockSizeException | BadPaddingException signatureEx) {
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | NoSuchPaddingException
|
||||
| IllegalBlockSizeException | BadPaddingException signatureEx) {
|
||||
plugin.getLog().error("Invalid signature from player {}", sender, signatureEx);
|
||||
return false;
|
||||
}
|
||||
@ -227,7 +230,9 @@ public class ProtocolLibListener extends PacketAdapter {
|
||||
plugin.getLog().trace("GameProfile {} with {} connecting", sessionKey, username);
|
||||
|
||||
packetEvent.getAsyncMarker().incrementProcessingDelay();
|
||||
Runnable nameCheckTask = new NameCheckTask(plugin, random, player, packetEvent, username, clientKey.orElse(null), keyPair.getPublic());
|
||||
Runnable nameCheckTask = new NameCheckTask(
|
||||
plugin, random, player, packetEvent, username, clientKey.orElse(null), keyPair.getPublic()
|
||||
);
|
||||
plugin.getScheduler().runAsync(nameCheckTask);
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ class ProtocolLibLoginSource implements LoginSource {
|
||||
private final String serverId = "";
|
||||
private byte[] verifyToken;
|
||||
|
||||
public ProtocolLibLoginSource(Player player, Random random, PublicKey serverPublicKey, ClientPublicKey clientKey) {
|
||||
ProtocolLibLoginSource(Player player, Random random, PublicKey serverPublicKey, ClientPublicKey clientKey) {
|
||||
this.player = player;
|
||||
this.random = random;
|
||||
this.publicKey = serverPublicKey;
|
||||
@ -126,11 +126,11 @@ class ProtocolLibLoginSource implements LoginSource {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + '{' +
|
||||
"player=" + player +
|
||||
", random=" + random +
|
||||
", serverId='" + serverId + '\'' +
|
||||
", verifyToken=" + Arrays.toString(verifyToken) +
|
||||
'}';
|
||||
return this.getClass().getSimpleName() + '{'
|
||||
+ "player=" + player
|
||||
+ ", random=" + random
|
||||
+ ", serverId='" + serverId + '\''
|
||||
+ ", verifyToken=" + Arrays.toString(verifyToken)
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,9 @@ public class VerifyResponseTask implements Runnable {
|
||||
private static final Class<?> ENCRYPTION_CLASS;
|
||||
|
||||
static {
|
||||
ENCRYPTION_CLASS = MinecraftReflection.getMinecraftClass("util." + ENCRYPTION_CLASS_NAME, ENCRYPTION_CLASS_NAME);
|
||||
ENCRYPTION_CLASS = MinecraftReflection.getMinecraftClass(
|
||||
"util." + ENCRYPTION_CLASS_NAME, ENCRYPTION_CLASS_NAME
|
||||
);
|
||||
}
|
||||
|
||||
private final FastLoginBukkit plugin;
|
||||
@ -144,7 +146,11 @@ public class VerifyResponseTask implements Runnable {
|
||||
encryptConnection(session, requestedUsername, response.get());
|
||||
} else {
|
||||
//user tried to fake an authentication
|
||||
disconnect("invalid-session", "GameProfile {} ({}) tried to log in with an invalid session. ServerId: {}", session.getRequestUsername(), socketAddress, serverId);
|
||||
disconnect(
|
||||
"invalid-session",
|
||||
"GameProfile {} ({}) tried to log in with an invalid session. ServerId: {}",
|
||||
session.getRequestUsername(), socketAddress, serverId
|
||||
);
|
||||
}
|
||||
} catch (IOException ioEx) {
|
||||
disconnect("error-kick", "Failed to connect to session server", ioEx);
|
||||
|
@ -60,8 +60,8 @@ public class ProtocolLoginSource implements LoginSource {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + '{' +
|
||||
"loginStartEvent=" + loginStartEvent +
|
||||
'}';
|
||||
return this.getClass().getSimpleName() + '{'
|
||||
+ "loginStartEvent=" + loginStartEvent
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
@ -112,15 +112,16 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
|
||||
}
|
||||
|
||||
@Override
|
||||
public FastLoginPreLoginEvent callFastLoginPreLoginEvent(String username, ProtocolLoginSource source, StoredProfile profile) {
|
||||
public FastLoginPreLoginEvent callFastLoginPreLoginEvent(String username, ProtocolLoginSource source,
|
||||
StoredProfile profile) {
|
||||
BukkitFastLoginPreLoginEvent event = new BukkitFastLoginPreLoginEvent(username, source, profile);
|
||||
plugin.getServer().getPluginManager().callEvent(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestPremiumLogin(ProtocolLoginSource source, StoredProfile profile, String username
|
||||
, boolean registered) {
|
||||
public void requestPremiumLogin(ProtocolLoginSource source, StoredProfile profile, String username,
|
||||
boolean registered) {
|
||||
source.enableOnlinemode();
|
||||
|
||||
String ip = source.getAddress().getAddress().getHostAddress();
|
||||
|
@ -31,7 +31,7 @@ import com.github.games647.fastlogin.bukkit.hook.CrazyLoginHook;
|
||||
import com.github.games647.fastlogin.bukkit.hook.LogItHook;
|
||||
import com.github.games647.fastlogin.bukkit.hook.LoginSecurityHook;
|
||||
import com.github.games647.fastlogin.bukkit.hook.UltraAuthHook;
|
||||
import com.github.games647.fastlogin.bukkit.hook.xAuthHook;
|
||||
import com.github.games647.fastlogin.bukkit.hook.XAuthHook;
|
||||
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
@ -95,7 +95,7 @@ public class DelayedAuthHook implements Runnable {
|
||||
try {
|
||||
List<Class<? extends AuthPlugin<Player>>> hooks = Arrays.asList(AuthMeHook.class,
|
||||
CrazyLoginHook.class, LogItHook.class, LoginSecurityHook.class, UltraAuthHook.class,
|
||||
xAuthHook.class);
|
||||
XAuthHook.class);
|
||||
|
||||
for (Class<? extends AuthPlugin<Player>> clazz : hooks) {
|
||||
String pluginName = clazz.getSimpleName();
|
||||
|
@ -40,7 +40,8 @@ import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
|
||||
public class FloodgateAuthTask extends FloodgateManagement<Player, CommandSender, BukkitLoginSession, FastLoginBukkit> {
|
||||
|
||||
public FloodgateAuthTask(FastLoginCore<Player, CommandSender, FastLoginBukkit> core, Player player, FloodgatePlayer floodgatePlayer) {
|
||||
public FloodgateAuthTask(FastLoginCore<Player, CommandSender, FastLoginBukkit> core, Player player,
|
||||
FloodgatePlayer floodgatePlayer) {
|
||||
super(core, player, floodgatePlayer);
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,10 @@ public class BungeeLoginSession extends LoginSession {
|
||||
|
||||
@Override
|
||||
public synchronized String toString() {
|
||||
return this.getClass().getSimpleName() + '{' +
|
||||
"alreadySaved=" + alreadySaved +
|
||||
", alreadyLogged=" + alreadyLogged +
|
||||
", registered=" + registered +
|
||||
"} " + super.toString();
|
||||
return this.getClass().getSimpleName() + '{'
|
||||
+ "alreadySaved=" + alreadySaved
|
||||
+ ", alreadyLogged=" + alreadyLogged
|
||||
+ ", registered=" + registered
|
||||
+ "} " + super.toString();
|
||||
}
|
||||
}
|
||||
|
@ -72,8 +72,8 @@ public class BungeeLoginSource implements LoginSource {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + '{' +
|
||||
"connection=" + connection +
|
||||
'}';
|
||||
return this.getClass().getSimpleName() + '{'
|
||||
+ "connection=" + connection
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class ConnectListener implements Listener {
|
||||
|
||||
private static final String UUID_FIELD_NAME = "uniqueId";
|
||||
private static final MethodHandle uniqueIdSetter;
|
||||
private static final MethodHandle UNIQUE_ID_SETTER;
|
||||
|
||||
static {
|
||||
MethodHandle setHandle = null;
|
||||
@ -91,7 +91,7 @@ public class ConnectListener implements Listener {
|
||||
);
|
||||
}
|
||||
|
||||
uniqueIdSetter = setHandle;
|
||||
UNIQUE_ID_SETTER = setHandle;
|
||||
}
|
||||
|
||||
private final FastLoginBungee plugin;
|
||||
@ -155,7 +155,7 @@ public class ConnectListener implements Listener {
|
||||
playerProfile.setId(verifiedUUID);
|
||||
|
||||
// BungeeCord will do this automatically so override it on disabled option
|
||||
if (uniqueIdSetter != null) {
|
||||
if (UNIQUE_ID_SETTER != null) {
|
||||
InitialHandler initialHandler = (InitialHandler) connection;
|
||||
|
||||
if (!plugin.getCore().getConfig().get("premiumUuid", true)) {
|
||||
@ -179,7 +179,7 @@ public class ConnectListener implements Listener {
|
||||
// BungeeCord only allows setting the UUID in PreLogin events and before requesting online mode
|
||||
// However if online mode is requested, it will override previous values
|
||||
// So we have to do it with reflection
|
||||
uniqueIdSetter.invokeExact(connection, offlineUUID);
|
||||
UNIQUE_ID_SETTER.invokeExact(connection, offlineUUID);
|
||||
|
||||
String format = "Overridden UUID from {} to {} (based of {}) on {}";
|
||||
plugin.getLog().info(format, oldPremiumId, offlineUUID, username, connection);
|
||||
|
@ -73,8 +73,8 @@ public class AsyncToggleMessage implements Runnable {
|
||||
playerProfile.setPremium(false);
|
||||
playerProfile.setId(null);
|
||||
core.getStorage().save(playerProfile);
|
||||
PremiumToggleReason reason = (!isPlayerSender || !sender.getName().equalsIgnoreCase(playerProfile.getName())) ?
|
||||
PremiumToggleReason.COMMAND_OTHER : PremiumToggleReason.COMMAND_SELF;
|
||||
PremiumToggleReason reason = (!isPlayerSender || !sender.getName().equalsIgnoreCase(playerProfile.getName()))
|
||||
? PremiumToggleReason.COMMAND_OTHER : PremiumToggleReason.COMMAND_SELF;
|
||||
core.getPlugin().getProxy().getPluginManager().callEvent(
|
||||
new BungeeFastLoginPremiumToggleEvent(playerProfile, reason));
|
||||
sendMessage("remove-premium");
|
||||
@ -89,8 +89,8 @@ public class AsyncToggleMessage implements Runnable {
|
||||
|
||||
playerProfile.setPremium(true);
|
||||
core.getStorage().save(playerProfile);
|
||||
PremiumToggleReason reason = (!isPlayerSender || !sender.getName().equalsIgnoreCase(playerProfile.getName())) ?
|
||||
PremiumToggleReason.COMMAND_OTHER : PremiumToggleReason.COMMAND_SELF;
|
||||
PremiumToggleReason reason = (!isPlayerSender || !sender.getName().equalsIgnoreCase(playerProfile.getName()))
|
||||
? PremiumToggleReason.COMMAND_OTHER : PremiumToggleReason.COMMAND_SELF;
|
||||
core.getPlugin().getProxy().getPluginManager().callEvent(
|
||||
new BungeeFastLoginPremiumToggleEvent(playerProfile, reason));
|
||||
sendMessage("add-premium");
|
||||
|
224
checkstyle.xml
Normal file
224
checkstyle.xml
Normal file
@ -0,0 +1,224 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
|
||||
SPDX-License-Identifier: MIT
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2022 games647 and contributors
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
Checkstyle configuration that checks the sun coding conventions from:
|
||||
|
||||
- the Java Language Specification at
|
||||
https://docs.oracle.com/javase/specs/jls/se11/html/index.html
|
||||
|
||||
- the Sun Code Conventions at https://www.oracle.com/java/technologies/javase/codeconventions-contents.html
|
||||
|
||||
- the Javadoc guidelines at
|
||||
https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html
|
||||
|
||||
- the JDK Api documentation https://docs.oracle.com/en/java/javase/11/
|
||||
|
||||
- some best practices
|
||||
|
||||
Checkstyle is very configurable. Be sure to read the documentation at
|
||||
https://checkstyle.org (or in your downloaded distribution).
|
||||
|
||||
Most Checks are configurable, be sure to consult the documentation.
|
||||
|
||||
To completely disable a check, just comment it out or delete it from the file.
|
||||
To suppress certain violations please review suppression filters.
|
||||
|
||||
Finally, it is worth reading the documentation.
|
||||
|
||||
-->
|
||||
|
||||
<module name="Checker">
|
||||
<!--
|
||||
If you set the basedir property below, then all reported file
|
||||
names will be relative to the specified directory. See
|
||||
https://checkstyle.org/config.html#Checker
|
||||
|
||||
<property name="basedir" value="${basedir}"/>
|
||||
-->
|
||||
<property name="severity" value="error"/>
|
||||
|
||||
<property name="fileExtensions" value="java, properties, xml"/>
|
||||
|
||||
<!-- Excludes all 'module-info.java' files -->
|
||||
<!-- See https://checkstyle.org/config_filefilters.html -->
|
||||
<module name="BeforeExecutionExclusionFileFilter">
|
||||
<property name="fileNamePattern" value="module\-info\.java$"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${org.checkstyle.sun.suppressionfilter.config}"
|
||||
default="checkstyle-suppressions.xml" />
|
||||
<property name="optional" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks that a package-info.java file exists for each package. -->
|
||||
<!-- See https://checkstyle.org/config_javadoc.html#JavadocPackage -->
|
||||
<!--<module name="JavadocPackage"/>-->
|
||||
|
||||
<!-- Checks whether files end with a new line. -->
|
||||
<!-- See https://checkstyle.org/config_misc.html#NewlineAtEndOfFile -->
|
||||
<module name="NewlineAtEndOfFile"/>
|
||||
|
||||
<!-- Checks that property files contain the same keys. -->
|
||||
<!-- See https://checkstyle.org/config_misc.html#Translation -->
|
||||
<module name="Translation"/>
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See https://checkstyle.org/config_sizes.html -->
|
||||
<module name="FileLength"/>
|
||||
<module name="LineLength">
|
||||
<property name="max" value="120"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See https://checkstyle.org/config_whitespace.html -->
|
||||
<module name="FileTabCharacter"/>
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See https://checkstyle.org/config_misc.html -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="\s+$"/>
|
||||
<property name="minimum" value="0"/>
|
||||
<property name="maximum" value="0"/>
|
||||
<property name="message" value="Line has trailing spaces."/>
|
||||
</module>
|
||||
|
||||
<!-- Checks for Headers -->
|
||||
<!-- See https://checkstyle.org/config_header.html -->
|
||||
<!-- <module name="Header"> -->
|
||||
<!-- <property name="headerFile" value="${checkstyle.header.file}"/> -->
|
||||
<!-- <property name="fileExtensions" value="java"/> -->
|
||||
<!-- </module> -->
|
||||
|
||||
<module name="TreeWalker">
|
||||
|
||||
<!-- Checks for Javadoc comments. -->
|
||||
<!-- See https://checkstyle.org/config_javadoc.html -->
|
||||
<module name="InvalidJavadocPosition"/>
|
||||
<module name="JavadocMethod"/>
|
||||
<!--<module name="JavadocType"/>-->
|
||||
<!--<module name="JavadocVariable"/>-->
|
||||
<!--<module name="JavadocStyle"/>-->
|
||||
<!--<module name="MissingJavadocMethod"/>-->
|
||||
|
||||
<!-- Checks for Naming Conventions. -->
|
||||
<!-- See https://checkstyle.org/config_naming.html -->
|
||||
<module name="ConstantName"/>
|
||||
<module name="LocalFinalVariableName"/>
|
||||
<module name="LocalVariableName"/>
|
||||
<module name="MemberName"/>
|
||||
<module name="MethodName"/>
|
||||
<module name="PackageName"/>
|
||||
<module name="ParameterName"/>
|
||||
<module name="StaticVariableName"/>
|
||||
<module name="TypeName"/>
|
||||
|
||||
<!-- Checks for imports -->
|
||||
<!-- See https://checkstyle.org/config_imports.html -->
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
|
||||
<module name="RedundantImport"/>
|
||||
<module name="UnusedImports">
|
||||
<property name="processJavadoc" value="false"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See https://checkstyle.org/config_sizes.html -->
|
||||
<module name="MethodLength"/>
|
||||
<module name="ParameterNumber"/>
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See https://checkstyle.org/config_whitespace.html -->
|
||||
<module name="EmptyForIteratorPad"/>
|
||||
<module name="GenericWhitespace"/>
|
||||
<module name="MethodParamPad"/>
|
||||
<module name="NoWhitespaceAfter"/>
|
||||
<module name="NoWhitespaceBefore"/>
|
||||
<module name="OperatorWrap"/>
|
||||
<module name="ParenPad"/>
|
||||
<module name="TypecastParenPad"/>
|
||||
<module name="WhitespaceAfter"/>
|
||||
<module name="WhitespaceAround"/>
|
||||
|
||||
<!-- Modifier Checks -->
|
||||
<!-- See https://checkstyle.org/config_modifier.html -->
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="RedundantModifier"/>
|
||||
|
||||
<!-- Checks for blocks. You know, those {}'s -->
|
||||
<!-- See https://checkstyle.org/config_blocks.html -->
|
||||
<module name="AvoidNestedBlocks"/>
|
||||
<module name="EmptyBlock"/>
|
||||
<module name="LeftCurly"/>
|
||||
<module name="NeedBraces"/>
|
||||
<module name="RightCurly"/>
|
||||
|
||||
<!-- Checks for common coding problems -->
|
||||
<!-- See https://checkstyle.org/config_coding.html -->
|
||||
<module name="EmptyStatement"/>
|
||||
<module name="EqualsHashCode"/>
|
||||
<module name="IllegalInstantiation"/>
|
||||
<module name="InnerAssignment"/>
|
||||
<!--<module name="MagicNumber"/>-->
|
||||
<module name="MissingSwitchDefault"/>
|
||||
<module name="MultipleVariableDeclarations"/>
|
||||
<module name="SimplifyBooleanExpression"/>
|
||||
<module name="SimplifyBooleanReturn"/>
|
||||
|
||||
<!-- Checks for class design -->
|
||||
<!-- See https://checkstyle.org/config_design.html -->
|
||||
<!--<module name="DesignForExtension"/>-->
|
||||
<module name="FinalClass"/>
|
||||
<module name="HideUtilityClassConstructor"/>
|
||||
<module name="InterfaceIsType"/>
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See https://checkstyle.org/config_misc.html -->
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<!--<module name="FinalParameters"/>-->
|
||||
<!-- <module name="TodoComment"/>-->
|
||||
<module name="UpperEll"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_filters.html#SuppressionXpathFilter -->
|
||||
<module name="SuppressionXpathFilter">
|
||||
<property name="file" value="${org.checkstyle.sun.suppressionxpathfilter.config}"
|
||||
default="checkstyle-xpath-suppressions.xml" />
|
||||
<property name="optional" value="true"/>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
|
||||
</module>
|
@ -37,7 +37,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.jul.JDK14LoggerAdapter;
|
||||
|
||||
public class CommonUtil {
|
||||
public final class CommonUtil {
|
||||
|
||||
private static final char COLOR_CHAR = '&';
|
||||
private static final char TRANSLATED_CHAR = '§';
|
||||
|
@ -114,11 +114,20 @@ public class StoredProfile extends Profile {
|
||||
|
||||
@Override
|
||||
public synchronized boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof StoredProfile that)) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof StoredProfile that)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return rowId == that.rowId && premium == that.premium
|
||||
&& Objects.equals(lastIp, that.lastIp) && lastLogin.equals(that.lastLogin);
|
||||
&& Objects.equals(lastIp, that.lastIp) && lastLogin.equals(that.lastLogin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -128,11 +137,11 @@ public class StoredProfile extends Profile {
|
||||
|
||||
@Override
|
||||
public synchronized String toString() {
|
||||
return this.getClass().getSimpleName() + '{' +
|
||||
"rowId=" + rowId +
|
||||
", premium=" + premium +
|
||||
", lastIp='" + lastIp + '\'' +
|
||||
", lastLogin=" + lastLogin +
|
||||
"} " + super.toString();
|
||||
return this.getClass().getSimpleName() + '{'
|
||||
+ "rowId=" + rowId
|
||||
+ ", premium=" + premium
|
||||
+ ", lastIp='" + lastIp + '\''
|
||||
+ ", lastLogin=" + lastLogin
|
||||
+ "} " + super.toString();
|
||||
}
|
||||
}
|
||||
|
@ -36,42 +36,46 @@ import java.util.Optional;
|
||||
|
||||
/**
|
||||
* An extension to {@link MojangResolver} which allows connection using transparent reverse proxies.
|
||||
* The significant difference is that unlike MojangResolver from the CraftAPI implementation, which sends the "ip" parameter
|
||||
* when the hostIp parameter is an IPv4 address, but skips it for IPv6, this implementation leaves out the "ip" parameter
|
||||
* also for IPv4, effectively enabling transparent proxies to work.
|
||||
* The significant difference is that unlike MojangResolver from the CraftAPI implementation, which sends the
|
||||
* "ip" parameter when the hostIp parameter is an IPv4 address, but skips it for IPv6, this implementation leaves out
|
||||
* the "ip" parameter also for IPv4, effectively enabling transparent proxies to work.
|
||||
*
|
||||
* @author games647, Enginecrafter77
|
||||
*/
|
||||
public class ProxyAgnosticMojangResolver extends MojangResolver {
|
||||
/**
|
||||
* A formatting string containing a URL used to call the {@code hasJoined} method on mojang session servers.
|
||||
*
|
||||
* Formatting parameters:
|
||||
* 1. The username of the player in question
|
||||
* 2. The serverId of this server
|
||||
*/
|
||||
public static final String MOJANG_SESSIONSERVER_HASJOINED_CALL_URLFMT = "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=%s&serverId=%s";
|
||||
|
||||
@Override
|
||||
public Optional<Verification> hasJoined(String username, String serverHash, InetAddress hostIp) throws IOException
|
||||
{
|
||||
String url = String.format(MOJANG_SESSIONSERVER_HASJOINED_CALL_URLFMT, username, serverHash);
|
||||
private static final String HOST = "sessionserver.mojang.com";
|
||||
|
||||
HttpURLConnection conn = this.getConnection(url);
|
||||
int responseCode = conn.getResponseCode();
|
||||
/**
|
||||
* A formatting string containing a URL used to call the {@code hasJoined} method on mojang session servers.
|
||||
* <p>
|
||||
* Formatting parameters:
|
||||
* 1. The username of the player in question
|
||||
* 2. The serverId of this server
|
||||
*/
|
||||
public static final String ENDPOINT = "https://" + HOST + "/session/minecraft/hasJoined?username=%s&serverId=%s";
|
||||
|
||||
Verification verification = null;
|
||||
@Override
|
||||
public Optional<Verification> hasJoined(String username, String serverHash, InetAddress hostIp)
|
||||
throws IOException {
|
||||
String url = String.format(ENDPOINT, username, serverHash);
|
||||
|
||||
// Mojang session servers send HTTP 204 (NO CONTENT) when the authentication seems invalid
|
||||
// If that's not our case, the authentication is valid, and so we can parse the response.
|
||||
if(responseCode != HttpURLConnection.HTTP_NO_CONTENT)
|
||||
verification = this.parseRequest(conn, this::parseVerification);
|
||||
HttpURLConnection conn = this.getConnection(url);
|
||||
int responseCode = conn.getResponseCode();
|
||||
|
||||
return Optional.ofNullable(verification);
|
||||
}
|
||||
Verification verification = null;
|
||||
|
||||
// Functional implementation of InputStreamAction, used in hasJoined method in parseRequest call
|
||||
protected Verification parseVerification(InputStream input) throws IOException
|
||||
{
|
||||
return this.readJson(input, Verification.class);
|
||||
}
|
||||
// Mojang session servers send HTTP 204 (NO CONTENT) when the authentication seems invalid
|
||||
// If that's not our case, the authentication is valid, and so we can parse the response.
|
||||
if (responseCode != HttpURLConnection.HTTP_NO_CONTENT) {
|
||||
verification = this.parseRequest(conn, this::parseVerification);
|
||||
}
|
||||
|
||||
return Optional.ofNullable(verification);
|
||||
}
|
||||
|
||||
// Functional implementation of InputStreamAction, used in hasJoined method in parseRequest call
|
||||
protected Verification parseVerification(InputStream input) throws IOException {
|
||||
return this.readJson(input, Verification.class);
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ public class TickingRateLimiter implements RateLimiter {
|
||||
private final long expireTime;
|
||||
private int count;
|
||||
|
||||
public TimeRecord(long firstMinuteRecord, long expireTime) {
|
||||
TimeRecord(long firstMinuteRecord, long expireTime) {
|
||||
this.firstMinuteRecord = firstMinuteRecord;
|
||||
this.expireTime = expireTime;
|
||||
this.count = 1;
|
||||
|
@ -74,12 +74,12 @@ public abstract class BedrockService<B> {
|
||||
"Could not check whether Bedrock Player {}'s name conflicts a premium Java player's name.",
|
||||
username);
|
||||
|
||||
kickPlayer(source, username, "Could not check if your name conflicts an existing " +
|
||||
"premium Java account's name. This is usually a serverside error.");
|
||||
kickPlayer(source, username, "Could not check if your name conflicts an existing "
|
||||
+ "premium Java account's name. This is usually a serverside error.");
|
||||
} catch (RateLimitException rateLimitException) {
|
||||
core.getPlugin().getLog().warn("Mojang API rate limit hit");
|
||||
kickPlayer(source, username, "Could not check if your name conflicts an existing premium " +
|
||||
"Java account's name. Try again in a few minutes");
|
||||
kickPlayer(source, username, "Could not check if your name conflicts an existing premium "
|
||||
+ "Java account's name. Try again in a few minutes");
|
||||
}
|
||||
|
||||
if (premiumUUID.isPresent()) {
|
||||
|
@ -60,12 +60,16 @@ public class FloodgateService extends BedrockService<FloodgatePlayer> {
|
||||
*/
|
||||
public boolean isValidFloodgateConfigString(String key) {
|
||||
String value = core.getConfig().get(key).toString().toLowerCase(Locale.ENGLISH);
|
||||
if (!"true".equals(value) && !"linked".equals(value) && !"false".equals(value) && !"no-conflict".equals(value)) {
|
||||
core.getPlugin().getLog().error("Invalid value detected for {} in FastLogin/config.yml.", key);
|
||||
return false;
|
||||
switch (value) {
|
||||
case "true":
|
||||
case "linked":
|
||||
case "false":
|
||||
case "no-conflict":
|
||||
return true;
|
||||
default:
|
||||
core.getPlugin().getLog().error("Invalid value detected for {} in FastLogin/config.yml.", key);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -82,7 +86,7 @@ public class FloodgateService extends BedrockService<FloodgatePlayer> {
|
||||
|
||||
if ("false".equals(allowConflict)
|
||||
|| "linked".equals(allowConflict) && !isLinked) {
|
||||
super.checkNameConflict(username, source);
|
||||
super.checkNameConflict(username, source);
|
||||
} else {
|
||||
core.getPlugin().getLog().info("Skipping name conflict checking for player {}", username);
|
||||
}
|
||||
|
@ -79,10 +79,10 @@ public class ChangePremiumMessage implements ChannelMessage {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + '{' +
|
||||
"playerName='" + playerName + '\'' +
|
||||
", shouldEnable=" + willEnable +
|
||||
", isSourceInvoker=" + isSourceInvoker +
|
||||
'}';
|
||||
return this.getClass().getSimpleName() + '{'
|
||||
+ "playerName='" + playerName + '\''
|
||||
+ ", shouldEnable=" + willEnable
|
||||
+ ", isSourceInvoker=" + isSourceInvoker
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
@ -92,11 +92,11 @@ public class LoginActionMessage implements ChannelMessage {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + '{' +
|
||||
"type='" + type + '\'' +
|
||||
", playerName='" + playerName + '\'' +
|
||||
", proxyId=" + proxyId +
|
||||
'}';
|
||||
return this.getClass().getSimpleName() + '{'
|
||||
+ "type='" + type + '\''
|
||||
+ ", playerName='" + playerName + '\''
|
||||
+ ", proxyId=" + proxyId
|
||||
+ '}';
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
|
@ -122,7 +122,8 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
||||
}
|
||||
|
||||
// Initialize the resolver based on the config parameter
|
||||
this.resolver = this.config.getBoolean("useProxyAgnosticResolver", false) ? new ProxyAgnosticMojangResolver() : new MojangResolver();
|
||||
this.resolver = this.config.getBoolean("useProxyAgnosticResolver", false)
|
||||
? new ProxyAgnosticMojangResolver() : new MojangResolver();
|
||||
|
||||
antiBot = createAntiBotService(config.getSection("anti-bot"));
|
||||
Set<Proxy> proxies = config.getStringList("proxies")
|
||||
@ -191,7 +192,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
||||
config = configProvider.load(reader, defaults);
|
||||
}
|
||||
|
||||
// explicitly add keys here, because Configuration.getKeys doesn't return the keys from the default configuration
|
||||
// explicitly add keys here, because Configuration.getKeys doesn't return the keys from the default config
|
||||
for (String key : defaults.getKeys()) {
|
||||
config.set(key, config.get(key));
|
||||
}
|
||||
@ -244,9 +245,13 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
||||
boolean useSSL = config.get("useSSL", false);
|
||||
|
||||
if (useSSL) {
|
||||
databaseConfig.addDataSourceProperty("allowPublicKeyRetrieval", config.getBoolean("allowPublicKeyRetrieval", false));
|
||||
databaseConfig.addDataSourceProperty("serverRSAPublicKeyFile", config.getString("ServerRSAPublicKeyFile"));
|
||||
databaseConfig.addDataSourceProperty("sslMode", config.getString("sslMode", "Required"));
|
||||
boolean publicKeyRetrieval = config.getBoolean("allowPublicKeyRetrieval", false);
|
||||
String rsaPublicKeyFile = config.getString("ServerRSAPublicKeyFile");
|
||||
String sslMode = config.getString("sslMode", "Required");
|
||||
|
||||
databaseConfig.addDataSourceProperty("allowPublicKeyRetrieval", publicKeyRetrieval);
|
||||
databaseConfig.addDataSourceProperty("serverRSAPublicKeyFile", rsaPublicKeyFile);
|
||||
databaseConfig.addDataSourceProperty("sslMode", sslMode);
|
||||
}
|
||||
|
||||
databaseConfig.setUsername(config.get("username", ""));
|
||||
@ -270,8 +275,8 @@ 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 either MySQL (Spigot, BungeeCord), SQLite (Spigot, Sponge) or "
|
||||
+ "MariaDB (Sponge, Velocity)", notFoundEx);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -106,9 +106,9 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
|
||||
}
|
||||
}
|
||||
} catch (RateLimitException rateLimitEx) {
|
||||
core.getPlugin().getLog().error("Mojang's rate limit reached for {}. The public IPv4 address of this" +
|
||||
" server issued more than 600 Name -> UUID requests within 10 minutes. After those 10" +
|
||||
" minutes we can make requests again.", username);
|
||||
core.getPlugin().getLog().error("Mojang's rate limit reached for {}. The public IPv4 address of this"
|
||||
+ " server issued more than 600 Name -> UUID requests within 10 minutes. After those 10"
|
||||
+ " minutes we can make requests again.", username);
|
||||
} catch (Exception ex) {
|
||||
core.getPlugin().getLog().error("Failed to check premium state for {}", username, ex);
|
||||
core.getPlugin().getLog().error("Failed to check premium state of {}", username, ex);
|
||||
|
@ -31,7 +31,7 @@ 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) {
|
||||
HikariConfig config, boolean useSSL) {
|
||||
super(core,
|
||||
buildJDBCUrl(driver, host, port, database),
|
||||
setParams(config, useSSL));
|
||||
|
27
pom.xml
27
pom.xml
@ -125,6 +125,33 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>3.1.2</version>
|
||||
<configuration>
|
||||
<configLocation>checkstyle.xml</configLocation>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<failsOnError>false</failsOnError>
|
||||
<linkXRef>false</linkXRef>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>10.3.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate</id>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<resources>
|
||||
|
@ -46,6 +46,7 @@ import com.velocitypowered.api.plugin.Plugin;
|
||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelRegistrar;
|
||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
|
||||
@ -73,7 +74,7 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
|
||||
private final Path dataDirectory;
|
||||
private final Logger logger;
|
||||
private final ConcurrentMap<InetSocketAddress, VelocityLoginSession> session = new MapMaker().weakKeys().makeMap();
|
||||
private static final String PROXY_ID_fILE = "proxyId.txt";
|
||||
private static final String PROXY_ID_FILE = "proxyId.txt";
|
||||
|
||||
private FastLoginCore<Player, CommandSource, FastLoginVelocity> core;
|
||||
private AsyncScheduler scheduler;
|
||||
@ -98,8 +99,10 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
|
||||
|
||||
server.getEventManager().register(this, new ConnectListener(this, core.getAntiBot()));
|
||||
server.getEventManager().register(this, new PluginMessageListener(this));
|
||||
server.getChannelRegistrar().register(MinecraftChannelIdentifier.create(getName(), ChangePremiumMessage.CHANGE_CHANNEL));
|
||||
server.getChannelRegistrar().register(MinecraftChannelIdentifier.create(getName(), SuccessMessage.SUCCESS_CHANNEL));
|
||||
|
||||
ChannelRegistrar channelRegistry = server.getChannelRegistrar();
|
||||
channelRegistry.register(MinecraftChannelIdentifier.create(getName(), ChangePremiumMessage.CHANGE_CHANNEL));
|
||||
channelRegistry.register(MinecraftChannelIdentifier.create(getName(), SuccessMessage.SUCCESS_CHANNEL));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@ -167,7 +170,7 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
|
||||
}
|
||||
|
||||
private void loadOrGenerateProxyId() {
|
||||
Path idFile = dataDirectory.resolve(PROXY_ID_fILE);
|
||||
Path idFile = dataDirectory.resolve(PROXY_ID_FILE);
|
||||
boolean shouldGenerate = false;
|
||||
|
||||
if (Files.exists(idFile)) {
|
||||
@ -182,7 +185,8 @@ public class FastLoginVelocity implements PlatformPlugin<CommandSource> {
|
||||
logger.error("Unable to load proxy id from '{}'", idFile.toAbsolutePath());
|
||||
logger.error("Detailed exception:", e);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.error("'{}' contains an invalid uuid! FastLogin will not work without a valid id.", idFile.toAbsolutePath());
|
||||
Path filePath = idFile.toAbsolutePath();
|
||||
logger.error("'{}' contains an invalid uuid! FastLogin will not work without a valid id.", filePath);
|
||||
}
|
||||
} else {
|
||||
shouldGenerate = true;
|
||||
|
@ -58,10 +58,10 @@ public class VelocityLoginSession extends LoginSession {
|
||||
|
||||
@Override
|
||||
public synchronized String toString() {
|
||||
return this.getClass().getSimpleName() + '{' +
|
||||
"alreadySaved=" + alreadySaved +
|
||||
", alreadyLogged=" + alreadyLogged +
|
||||
", registered=" + registered +
|
||||
"} " + super.toString();
|
||||
return this.getClass().getSimpleName() + '{'
|
||||
+ "alreadySaved=" + alreadySaved
|
||||
+ ", alreadyLogged=" + alreadyLogged
|
||||
+ ", registered=" + registered
|
||||
+ "} " + super.toString();
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ import com.velocitypowered.api.event.ResultedEvent;
|
||||
import java.util.Objects;
|
||||
|
||||
public class VelocityFastLoginAutoLoginEvent
|
||||
implements FastLoginAutoLoginEvent, ResultedEvent<ResultedEvent.GenericResult> {
|
||||
implements FastLoginAutoLoginEvent, ResultedEvent<ResultedEvent.GenericResult> {
|
||||
|
||||
private final LoginSession session;
|
||||
private final StoredProfile profile;
|
||||
@ -67,11 +67,11 @@ public class VelocityFastLoginAutoLoginEvent
|
||||
|
||||
@Override
|
||||
public GenericResult getResult() {
|
||||
return cancelled ? GenericResult.denied(): GenericResult.allowed();
|
||||
return cancelled ? GenericResult.denied() : GenericResult.allowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResult(GenericResult result) {
|
||||
cancelled = Objects.requireNonNull(result) != GenericResult.allowed();
|
||||
cancelled = Objects.requireNonNull(result) != GenericResult.allowed();
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,9 @@ public class ConnectListener {
|
||||
break;
|
||||
case Continue:
|
||||
default:
|
||||
Runnable asyncPremiumCheck = new AsyncPremiumCheck(plugin, connection, username, continuation, preLoginEvent);
|
||||
Runnable asyncPremiumCheck = new AsyncPremiumCheck(
|
||||
plugin, connection, username, continuation, preLoginEvent
|
||||
);
|
||||
plugin.getScheduler().runAsync(asyncPremiumCheck);
|
||||
break;
|
||||
}
|
||||
@ -118,8 +120,8 @@ public class ConnectListener {
|
||||
}
|
||||
|
||||
if (!plugin.getCore().getConfig().get("forwardSkin", true)) {
|
||||
List<Property> skinFreeProp = removeSkin(event.getGameProfile().getProperties());
|
||||
event.setGameProfile(event.getGameProfile().withProperties(skinFreeProp));
|
||||
List<Property> newProp = removeSkin(event.getGameProfile().getProperties());
|
||||
event.setGameProfile(event.getGameProfile().withProperties(newProp));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,8 +129,9 @@ public class ConnectListener {
|
||||
private List<GameProfile.Property> removeSkin(Collection<Property> oldProperties) {
|
||||
List<GameProfile.Property> newProperties = new ArrayList<>(oldProperties.size());
|
||||
for (GameProfile.Property property : oldProperties) {
|
||||
if (!"textures".equals(property.getName()))
|
||||
if (!"textures".equals(property.getName())) {
|
||||
newProperties.add(property);
|
||||
}
|
||||
}
|
||||
|
||||
return newProperties;
|
||||
|
@ -55,8 +55,9 @@ public class PluginMessageListener {
|
||||
public PluginMessageListener(FastLoginVelocity plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
this.successChannel = MinecraftChannelIdentifier.create(plugin.getName(), SuccessMessage.SUCCESS_CHANNEL).getId();
|
||||
this.changeChannel = MinecraftChannelIdentifier.create(plugin.getName(), ChangePremiumMessage.CHANGE_CHANNEL).getId();
|
||||
String prefix = plugin.getName();
|
||||
this.successChannel = MinecraftChannelIdentifier.create(prefix, SuccessMessage.SUCCESS_CHANNEL).getId();
|
||||
this.changeChannel = MinecraftChannelIdentifier.create(prefix, ChangePremiumMessage.CHANGE_CHANNEL).getId();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@ -95,8 +96,9 @@ public class PluginMessageListener {
|
||||
String playerName = changeMessage.getPlayerName();
|
||||
boolean isSourceInvoker = changeMessage.isSourceInvoker();
|
||||
if (changeMessage.shouldEnable()) {
|
||||
if (playerName.equals(forPlayer.getUsername()) && plugin.getCore().getConfig().get("premium-warning", true)
|
||||
&& !core.getPendingConfirms().contains(forPlayer.getUniqueId())) {
|
||||
Boolean premiumWarning = plugin.getCore().getConfig().get("premium-warning", true);
|
||||
if (playerName.equals(forPlayer.getUsername()) && premiumWarning
|
||||
&& !core.getPendingConfirms().contains(forPlayer.getUniqueId())) {
|
||||
String message = core.getMessage("premium-warning");
|
||||
forPlayer.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(message));
|
||||
core.getPendingConfirms().add(forPlayer.getUniqueId());
|
||||
@ -114,7 +116,7 @@ public class PluginMessageListener {
|
||||
}
|
||||
|
||||
private void onSuccessMessage(Player forPlayer) {
|
||||
if (forPlayer.isOnlineMode()){
|
||||
if (forPlayer.isOnlineMode()) {
|
||||
//bukkit module successfully received and force logged in the user
|
||||
//update only on success to prevent corrupt data
|
||||
VelocityLoginSession loginSession = plugin.getSession().get(forPlayer.getRemoteAddress());
|
||||
|
@ -49,7 +49,8 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
|
||||
private final PreLoginEvent preLoginEvent;
|
||||
private final InboundConnection connection;
|
||||
|
||||
public AsyncPremiumCheck(FastLoginVelocity plugin, InboundConnection connection, String username, Continuation continuation, PreLoginEvent preLoginEvent) {
|
||||
public AsyncPremiumCheck(FastLoginVelocity plugin, InboundConnection connection, String username,
|
||||
Continuation continuation, PreLoginEvent preLoginEvent) {
|
||||
super(plugin.getCore(), plugin.getCore().getAuthPluginHook(), plugin.getBedrockService());
|
||||
this.plugin = plugin;
|
||||
this.connection = connection;
|
||||
@ -69,7 +70,8 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
|
||||
}
|
||||
|
||||
@Override
|
||||
public FastLoginPreLoginEvent callFastLoginPreLoginEvent(String username, VelocityLoginSource source, StoredProfile profile) {
|
||||
public FastLoginPreLoginEvent callFastLoginPreLoginEvent(String username, VelocityLoginSource source,
|
||||
StoredProfile profile) {
|
||||
VelocityFastLoginPreLoginEvent event = new VelocityFastLoginPreLoginEvent(username, source, profile);
|
||||
try {
|
||||
return plugin.getProxy().getEventManager().fire(event).get();
|
||||
@ -86,7 +88,8 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
|
||||
public void requestPremiumLogin(VelocityLoginSource source, StoredProfile profile,
|
||||
String username, boolean registered) {
|
||||
source.enableOnlinemode();
|
||||
plugin.getSession().put(source.getConnection().getRemoteAddress(), new VelocityLoginSession(username, registered, profile));
|
||||
VelocityLoginSession session = new VelocityLoginSession(username, registered, profile);
|
||||
plugin.getSession().put(source.getConnection().getRemoteAddress(), session);
|
||||
|
||||
String ip = source.getAddress().getAddress().getHostAddress();
|
||||
plugin.getCore().getPendingLogin().put(ip + username, new Object());
|
||||
@ -94,6 +97,7 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
|
||||
|
||||
@Override
|
||||
public void startCrackedSession(VelocityLoginSource source, StoredProfile profile, String username) {
|
||||
plugin.getSession().put(source.getConnection().getRemoteAddress(), new VelocityLoginSession(username, false, profile));
|
||||
VelocityLoginSession session = new VelocityLoginSession(username, false, profile);
|
||||
plugin.getSession().put(source.getConnection().getRemoteAddress(), session);
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import com.github.games647.fastlogin.core.shared.event.FastLoginPremiumToggleEve
|
||||
import com.github.games647.fastlogin.velocity.FastLoginVelocity;
|
||||
import com.github.games647.fastlogin.velocity.event.VelocityFastLoginPremiumToggleEvent;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.proxy.ConsoleCommandSource;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
@ -45,16 +46,17 @@ public class AsyncToggleMessage implements Runnable {
|
||||
private final boolean isPlayerSender;
|
||||
|
||||
public AsyncToggleMessage(FastLoginCore<Player, CommandSource, FastLoginVelocity> core,
|
||||
CommandSource sender, String playerName, boolean toPremium, boolean playerSender) {
|
||||
CommandSource sender, String playerName, boolean toPremium, boolean playerSender) {
|
||||
this.core = core;
|
||||
this.sender = sender;
|
||||
this.targetPlayer = playerName;
|
||||
this.toPremium = toPremium;
|
||||
this.isPlayerSender = playerSender;
|
||||
if (sender instanceof Player)
|
||||
if (sender instanceof Player) {
|
||||
senderName = ((Player) sender).getUsername();
|
||||
else
|
||||
} else {
|
||||
senderName = "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -77,10 +79,10 @@ public class AsyncToggleMessage implements Runnable {
|
||||
playerProfile.setPremium(false);
|
||||
playerProfile.setId(null);
|
||||
core.getStorage().save(playerProfile);
|
||||
PremiumToggleReason reason = (!isPlayerSender || !senderName.equalsIgnoreCase(playerProfile.getName())) ?
|
||||
PremiumToggleReason.COMMAND_OTHER : PremiumToggleReason.COMMAND_SELF;
|
||||
PremiumToggleReason reason = (!isPlayerSender || !senderName.equalsIgnoreCase(playerProfile.getName()))
|
||||
? PremiumToggleReason.COMMAND_OTHER : PremiumToggleReason.COMMAND_SELF;
|
||||
core.getPlugin().getProxy().getEventManager().fire(
|
||||
new VelocityFastLoginPremiumToggleEvent(playerProfile, reason));
|
||||
new VelocityFastLoginPremiumToggleEvent(playerProfile, reason));
|
||||
sendMessage("remove-premium");
|
||||
}
|
||||
|
||||
@ -93,10 +95,11 @@ public class AsyncToggleMessage implements Runnable {
|
||||
|
||||
playerProfile.setPremium(true);
|
||||
core.getStorage().save(playerProfile);
|
||||
PremiumToggleReason reason = (!isPlayerSender || !senderName.equalsIgnoreCase(playerProfile.getName())) ?
|
||||
PremiumToggleReason.COMMAND_OTHER : PremiumToggleReason.COMMAND_SELF;
|
||||
PremiumToggleReason reason = (!isPlayerSender || !senderName.equalsIgnoreCase(playerProfile.getName()))
|
||||
?
|
||||
PremiumToggleReason.COMMAND_OTHER : PremiumToggleReason.COMMAND_SELF;
|
||||
core.getPlugin().getProxy().getEventManager().fire(
|
||||
new VelocityFastLoginPremiumToggleEvent(playerProfile, reason));
|
||||
new VelocityFastLoginPremiumToggleEvent(playerProfile, reason));
|
||||
sendMessage("add-premium");
|
||||
}
|
||||
|
||||
@ -105,7 +108,8 @@ public class AsyncToggleMessage implements Runnable {
|
||||
if (isPlayerSender) {
|
||||
sender.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(message));
|
||||
} else {
|
||||
core.getPlugin().getProxy().getConsoleCommandSource().sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(message));
|
||||
ConsoleCommandSource console = core.getPlugin().getProxy().getConsoleCommandSource();
|
||||
console.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,8 @@ public class ForceLoginTask
|
||||
private final boolean forcedOnlineMode;
|
||||
|
||||
public ForceLoginTask(FastLoginCore<Player, CommandSource, FastLoginVelocity> core,
|
||||
Player player, RegisteredServer server, VelocityLoginSession session, boolean forcedOnlineMode) {
|
||||
Player player, RegisteredServer server, VelocityLoginSession session,
|
||||
boolean forcedOnlineMode) {
|
||||
super(core, player, session);
|
||||
|
||||
this.server = server;
|
||||
|
Reference in New Issue
Block a user