Clean up methods names and documentation

This commit is contained in:
games647
2024-05-21 14:41:41 +02:00
parent e9643ee3e2
commit be2ec1e5a8
26 changed files with 97 additions and 109 deletions

View File

@ -8,14 +8,11 @@ So they don't need to enter passwords. This is also called auto login (auto-logi
* Detect paid accounts from others
* Automatically login paid accounts (premium)
* Support various of auth plugins
* Cauldron support
* Forge/Sponge message support
* Premium UUID support
* Forward skins
* Detect username changed and will update the existing database record
* BungeeCord support
* BungeeCord/Velocity support
* Auto register new premium players
* Plugin: ProtocolSupport is supported and can be used as an alternative to ProtocolLib
* No client modifications needed
* Good performance by using async operations
* Locale messages
@ -103,8 +100,8 @@ This plugin performs network requests to:
### Spigot/Paper
1. Download and install ProtocolLib/ProtocolSupport
2. Download and install FastLogin (or `FastLoginBukkit` for newer versions)
3. Set your server in offline mode by setting the value `onlinemode` in your server.properties to false
2. Download and install `FastLoginBukkit`
3. Set your server in offline mode by setting the value `onlinemode` in your server.properties to `false`
### BungeeCord/Waterfall or Velocity
@ -119,8 +116,8 @@ Install the plugin on both platforms, that is proxy (BungeeCord or Velocity) and
4. Activate ip forwarding in your proxy config
5. Check your database settings in the config of FastLogin on your proxy
* The proxies only ship with a limited set of drivers where Spigot supports more. Therefore, these are supported:
* BungeeCord: `com.mysql.jdbc.Driver` for MySQL/MariaDB
* Velocity: `fastlogin.mariadb.jdbc.Driver` for MySQL/MariaDB
* BungeeCord: `mysql` for MySQL/MariaDB
* Velocity: `mariadb` for MySQL/MariaDB
* Note the embedded file storage SQLite is not available
* MySQL/MariaDB requires an external database server running. Check your server provider if there is one available
or install one.

View File

@ -122,14 +122,6 @@
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
<repository>
<id>sonatype-snapshots</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<!-- ProtocolLib -->
<repository>
<id>dmulloy2-repo</id>

View File

@ -47,7 +47,6 @@ public class BukkitLoginSession extends LoginSession {
private final ClientPublicKey clientPublicKey;
private boolean verified;
private SkinProperty skinProperty;
public BukkitLoginSession(String username, byte[] verifyToken, ClientPublicKey publicKey, boolean registered,
@ -109,7 +108,7 @@ public class BukkitLoginSession extends LoginSession {
*
* @param verified whether the player has valid session
*/
public synchronized void setVerified(boolean verified) {
public synchronized void setVerifiedPremium(boolean verified) {
this.verified = verified;
}
@ -118,7 +117,7 @@ public class BukkitLoginSession extends LoginSession {
*
* @return whether the player has a valid session
*/
public synchronized boolean isVerified() {
public synchronized boolean isVerifiedPremium() {
return verified;
}
}

View File

@ -95,7 +95,7 @@ public class CrackedCommand extends ToggleCommand {
}
//existing player is already cracked
if (profile.isSaved() && !profile.isOnlinemodePreferred()) {
if (profile.isExistingPlayer() && !profile.isOnlinemodePreferred()) {
plugin.getCore().sendLocaleMessage("not-premium-other", sender);
} else {
plugin.getCore().sendLocaleMessage("remove-premium", sender);

View File

@ -45,9 +45,9 @@ import java.lang.reflect.Field;
* <p>
* Project page:
* <p>
* Bukkit: <a href="https://dev.bukkit.org/bukkit-plugins/authme-reloaded/">...</a>
* <a href="https://dev.bukkit.org/bukkit-plugins/authme-reloaded/">Bukkit</a>
* <p>
* Spigot: <a href="https://www.spigotmc.org/resources/authme-reloaded.6269/">...</a>
* <a href="https://www.spigotmc.org/resources/authme-reloaded.6269/">Spigot</a>
*/
public class AuthMeHook implements AuthPlugin<Player>, Listener {
@ -76,7 +76,7 @@ public class AuthMeHook implements AuthPlugin<Player>, Listener {
Player player = restoreSessionEvent.getPlayer();
BukkitLoginSession session = plugin.getSession(player.spigot().getRawAddress());
if (session != null && session.isVerified()) {
if (session != null && session.isVerifiedPremium()) {
restoreSessionEvent.setCancelled(true);
}
}

View File

@ -46,7 +46,7 @@ import java.util.concurrent.Future;
* <p>
* Project page:
* <p>
* Bukkit: <a href="https://dev.bukkit.org/server-mods/crazylogin/">...</a>
* <a href="https://dev.bukkit.org/server-mods/crazylogin/">Bukkit</a>
*/
public class CrazyLoginHook implements AuthPlugin<Player> {

View File

@ -39,9 +39,9 @@ import org.bukkit.entity.Player;
* <p>
* Project page:
* <p>
* Bukkit: <a href="https://dev.bukkit.org/bukkit-plugins/loginsecurity/">...</a>
* <a href="https://dev.bukkit.org/bukkit-plugins/loginsecurity/">Bukkit</a>
* <p>
* Spigot: <a href="https://www.spigotmc.org/resources/loginsecurity.19362/">...</a>
* <a href="https://www.spigotmc.org/resources/loginsecurity.19362/">Spigot</a>
*/
public class LoginSecurityHook implements AuthPlugin<Player> {

View File

@ -38,9 +38,9 @@ import java.util.concurrent.Future;
/**
* Project page:
* <p>
* Bukkit: <a href="https://dev.bukkit.org/bukkit-plugins/ultraauth-aa/">...</a>
* <a href="https://dev.bukkit.org/bukkit-plugins/ultraauth-aa/">Bukkit</a>
* <p>
* Spigot: <a href="https://www.spigotmc.org/resources/ultraauth.17044/">...</a>
* <a href="https://www.spigotmc.org/resources/ultraauth.17044/">Spigot</a>
*/
public class UltraAuthHook implements AuthPlugin<Player> {

View File

@ -40,7 +40,7 @@ import java.util.concurrent.Future;
* <p>
* Project page:
* <p>
* Bukkit: <a href="https://dev.bukkit.org/bukkit-plugins/xauth/">...</a>
* <a href="https://dev.bukkit.org/bukkit-plugins/xauth/">Bukkit</a>
*/
public class XAuthHook implements AuthPlugin<Player> {

View File

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

View File

@ -52,6 +52,7 @@ import io.netty.util.AttributeKey;
import lombok.val;
import org.bukkit.entity.Player;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
import org.jetbrains.annotations.NotNull;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
@ -114,22 +115,10 @@ public class ProtocolLibListener extends PacketAdapter {
}
Player sender = packetEvent.getPlayer();
PacketType packetType = packetEvent.getPacketType();
PacketType packetType = getOverriddenType(packetEvent.getPacketType());
plugin.getLog().info("New packet {} from {}", packetType, sender);
try {
if (packetType.isDynamic()) {
String vanillaName = packetType.getPacketClass().getName();
plugin.getLog().info("Overriding packet type for unregistered packet type to fix ProtocolLib bug");
if (vanillaName.endsWith("ServerboundHelloPacket")) {
packetType = START;
}
if (vanillaName.endsWith("ServerboundKeyPacket")) {
packetType = ENCRYPTION_BEGIN;
}
}
if (packetType == START) {
if (plugin.getFloodgateService() != null) {
boolean success = processFloodgateTasks(packetEvent);
@ -169,6 +158,22 @@ public class ProtocolLibListener extends PacketAdapter {
}
}
private @NotNull PacketType getOverriddenType(PacketType packetType) {
if (packetType.isDynamic()) {
String vanillaName = packetType.getPacketClass().getName();
plugin.getLog().info("Overriding packet type for unregistered packet type to fix ProtocolLib bug");
if (vanillaName.endsWith("ServerboundHelloPacket")) {
return START;
}
if (vanillaName.endsWith("ServerboundKeyPacket")) {
return ENCRYPTION_BEGIN;
}
}
return packetType;
}
private void onEncryptionBegin(PacketEvent packetEvent, Player sender) {
byte[] sharedSecret = packetEvent.getPacket().getByteArrays().read(0);
@ -240,7 +245,7 @@ public class ProtocolLibListener extends PacketAdapter {
PacketContainer packet = packetEvent.getPacket();
Optional<ClientPublicKey> clientKey;
if (new MinecraftVersion(1, 19, 3).atOrAbove()) {
// public key sent separate
// public key is sent separate
clientKey = Optional.empty();
} else {
val profileKey = packet.getOptionals(BukkitConverters.getWrappedPublicKeyDataConverter())

View File

@ -51,7 +51,6 @@ class ProtocolLibLoginSource implements LoginSource {
private final ClientPublicKey clientKey;
private final PublicKey publicKey;
private final String serverId = "";
private byte[] verifyToken;
ProtocolLibLoginSource(Player player, Random random, PublicKey serverPublicKey, ClientPublicKey clientKey) {
@ -72,7 +71,7 @@ class ProtocolLibLoginSource implements LoginSource {
*/
PacketContainer newPacket = new PacketContainer(ENCRYPTION_BEGIN);
newPacket.getStrings().write(0, serverId);
newPacket.getStrings().write(0, "");
StructureModifier<PublicKey> keyModifier = newPacket.getSpecificModifier(PublicKey.class);
int verifyField = 0;
if (keyModifier.getFields().isEmpty()) {
@ -117,10 +116,6 @@ class ProtocolLibLoginSource implements LoginSource {
return clientKey;
}
public String getServerId() {
return serverId;
}
public byte[] getVerifyToken() {
return verifyToken.clone();
}
@ -130,7 +125,6 @@ class ProtocolLibLoginSource implements LoginSource {
return this.getClass().getSimpleName() + '{'
+ "player=" + player
+ ", random=" + random
+ ", serverId='" + serverId + '\''
+ ", verifyToken=" + Arrays.toString(verifyToken)
+ '}';
}

View File

@ -195,7 +195,7 @@ public class VerifyResponseTask implements Runnable {
session.setVerifiedUsername(realUsername);
session.setUuid(verification.getId());
session.setVerified(true);
session.setVerifiedPremium(true);
setPremiumUUID(session.getUuid());
receiveFakeStartPacket(realUsername, session.getClientPublicKey(), session.getUuid());

View File

@ -101,7 +101,7 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
BukkitLoginSession session = plugin.getSession(address);
if (session != null && profileCompleteEvent.getConnection().getProfile().isOnlineMode()) {
session.setVerified(true);
session.setVerifiedPremium(true);
if (!plugin.getConfig().getBoolean("premiumUuid")) {
String username = Optional.ofNullable(profileCompleteEvent.getForcedName())

View File

@ -49,7 +49,7 @@ public class FloodgateAuthTask extends FloodgateManagement<Player, CommandSender
BukkitLoginSession session = new BukkitLoginSession(player.getName(), isRegistered, profile);
// enable auto login based on the value of 'autoLoginFloodgate' in config.yml
session.setVerified(isAutoAuthAllowed(autoLoginFloodgate));
session.setVerifiedPremium(isAutoAuthAllowed(autoLoginFloodgate));
// run login task
Runnable forceLoginTask = new ForceLoginTask(core.getPlugin().getCore(), player, session);

View File

@ -103,6 +103,6 @@ public class ForceLoginTask extends ForceLoginManagement<Player, CommandSender,
@Override
public boolean isOnlineMode() {
return session.isVerified();
return session.isVerifiedPremium();
}
}

View File

@ -64,7 +64,7 @@ public class AsyncToggleMessage implements Runnable {
private void turnOffPremium() {
StoredProfile playerProfile = core.getStorage().loadProfile(targetPlayer);
//existing player is already cracked
if (playerProfile.isSaved() && !playerProfile.isOnlinemodePreferred()) {
if (playerProfile.isExistingPlayer() && !playerProfile.isOnlinemodePreferred()) {
sendMessage("not-premium");
return;
}

View File

@ -82,7 +82,7 @@ public abstract class FloodgateManagement<P extends C, C, L extends LoginSession
profile = core.getStorage().loadProfile(username);
if (profile.isSaved()) {
if (profile.isExistingPlayer()) {
if (profile.isFloodgateMigrated()) {
if (profile.getFloodgate() == FloodgateState.TRUE && isLinked) {
core.getPlugin().getLog()

View File

@ -71,60 +71,65 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
} else {
profile.setFloodgate(FloodgateState.FALSE);
core.getPlugin().getLog().info(
"Player {} will be migrated to the v2 database schema as a JAVA user", username);
"Player {} will be migrated to the v2 database schema as a JAVA user", username
);
}
callFastLoginPreLoginEvent(username, source, profile);
Configuration config = core.getConfig();
String ip = source.getAddress().getAddress().getHostAddress();
profile.setLastIp(ip);
try {
if (profile.isSaved()) {
if (profile.isOnlinemodePreferred()) {
core.getPlugin().getLog().info("Requesting premium login for registered player: {}", username);
requestPremiumLogin(source, profile, username, true);
} else {
if (isValidUsername(source, profile)) {
startCrackedSession(source, profile, username);
}
}
if (profile.isExistingPlayer()) {
if (profile.isOnlinemodePreferred()) {
core.getPlugin().getLog().info("Requesting premium login for registered player: {}", username);
requestPremiumLogin(source, profile, username, true);
} else {
if (core.hasFailedLogin(ip, username)) {
core.getPlugin().getLog().info("Second attempt login -> cracked {}", username);
//first login request failed so make a cracked session
startCrackedSession(source, profile, username);
return;
}
Optional<Profile> premiumUUID = Optional.empty();
if (config.get("nameChangeCheck", false) || config.get("autoRegister", false)) {
premiumUUID = core.getResolver().findProfile(username);
}
if (!premiumUUID.isPresent()
|| (!checkNameChange(source, username, premiumUUID.get())
&& !checkPremiumName(source, username, profile))) {
//nothing detected the player as premium -> start a cracked session
if (core.getConfig().get("switchMode", false)) {
source.kick(core.getMessage("switch-kick-message"));
return;
}
if (isValidUsername(source, profile)) {
startCrackedSession(source, profile, username);
}
}
} else {
performNewPlayerLogin(username, source, ip, profile);
}
}
private void performNewPlayerLogin(String username, S source, String ip, StoredProfile profile) {
try {
if (core.hasFailedLogin(ip, username)) {
core.getPlugin().getLog().info("Second attempt login -> cracked {}", username);
//first login request failed so make a cracked session
startCrackedSession(source, profile, username);
return;
}
Configuration config = core.getConfig();
Optional<Profile> premiumUUID = Optional.empty();
if (config.get("nameChangeCheck", false) || config.get("autoRegister", false)) {
premiumUUID = core.getResolver().findProfile(username);
}
if (!premiumUUID.isPresent()
|| (!isNameChanged(source, username, premiumUUID.get())
&& !isUsernameAvailable(source, username, profile))) {
//nothing detected the player as premium -> start a cracked session
if (core.getConfig().get("switchMode", false)) {
source.kick(core.getMessage("switch-kick-message"));
return;
}
startCrackedSession(source, profile, username);
}
} 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);
+ " 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 of {}", username, ex);
}
}
protected boolean isValidUsername(LoginSource source, StoredProfile profile) throws Exception {
protected boolean isValidUsername(LoginSource source, StoredProfile profile) {
if (bedrockService != null && bedrockService.isUsernameForbidden(profile)) {
core.getPlugin().getLog().info("Floodgate Prefix detected on cracked player");
source.kick("Your username contains illegal characters");
@ -134,7 +139,7 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
return true;
}
private boolean checkPremiumName(S source, String username, StoredProfile profile) throws Exception {
private boolean isUsernameAvailable(S source, String username, StoredProfile profile) throws Exception {
core.getPlugin().getLog().info("GameProfile {} uses a premium username", username);
if (core.getConfig().get("autoRegister", false) && (authHook == null || !authHook.isRegistered(username))) {
requestPremiumLogin(source, profile, username, false);
@ -144,7 +149,7 @@ public abstract class JoinManagement<P extends C, C, S extends LoginSource> {
return false;
}
private boolean checkNameChange(S source, String username, Profile profile) {
private boolean isNameChanged(S source, String username, Profile profile) {
//user not exists in the db
if (core.getConfig().get("nameChangeCheck", false)) {
StoredProfile storedProfile = core.getStorage().loadProfile(profile.getId());

View File

@ -31,7 +31,7 @@ public interface LoginSource {
void enableOnlinemode() throws Exception;
void kick(String message) throws Exception;
void kick(String message);
InetSocketAddress getAddress();
}

View File

@ -176,7 +176,7 @@ public abstract class SQLStorage implements AuthStorage {
playerProfile.getSaveLock().lock();
try {
if (playerProfile.isSaved()) {
if (playerProfile.isExistingPlayer()) {
try (PreparedStatement saveStmt = con.prepareStatement(UPDATE_PROFILE)) {
saveStmt.setString(1, uuid);
saveStmt.setString(2, playerProfile.getName());

View File

@ -68,7 +68,7 @@ public class StoredProfile extends Profile {
return saveLock;
}
public synchronized boolean isSaved() {
public synchronized boolean isExistingPlayer() {
return rowId >= 0;
}

View File

@ -9,7 +9,7 @@
# problem. Low level firewalls like uwf (or iptables direct) are more efficient than a Minecraft plugin. TCP reverse
# proxies could also be used and offload some work even to different host.
#
# The settings wil limit how many connections this plugin will handle. After hitting this limit. FastLogin will
# The settings will limit how many connections this plugin will handle. After hitting this limit. FastLogin will
# completely ignore incoming connections. Effectively there will be no database requests and network requests.
# Therefore, auto logins won't be possible.
anti-bot:

View File

@ -66,8 +66,4 @@ public class VelocityLoginSource implements LoginSource {
public InetSocketAddress getAddress() {
return connection.getRemoteAddress();
}
public InboundConnection getConnection() {
return connection;
}
}

View File

@ -82,7 +82,7 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
String username, boolean registered) {
source.enableOnlinemode();
VelocityLoginSession session = new VelocityLoginSession(username, registered, profile);
plugin.getSession().put(source.getConnection().getRemoteAddress(), session);
plugin.getSession().put(source.getAddress(), session);
String ip = source.getAddress().getAddress().getHostAddress();
plugin.getCore().addLoginAttempt(ip, username);
@ -91,6 +91,6 @@ public class AsyncPremiumCheck extends JoinManagement<Player, CommandSource, Vel
@Override
public void startCrackedSession(VelocityLoginSource source, StoredProfile profile, String username) {
VelocityLoginSession session = new VelocityLoginSession(username, false, profile);
plugin.getSession().put(source.getConnection().getRemoteAddress(), session);
plugin.getSession().put(source.getAddress(), session);
}
}

View File

@ -51,8 +51,8 @@ public class AsyncToggleMessage implements Runnable {
this.targetPlayer = playerName;
this.toPremium = toPremium;
this.isPlayerSender = playerSender;
if (sender instanceof Player) {
senderName = ((Player) sender).getUsername();
if (sender instanceof Player playSender) {
senderName = playSender.getUsername();
} else {
senderName = "";
}
@ -70,7 +70,7 @@ public class AsyncToggleMessage implements Runnable {
private void turnOffPremium() {
StoredProfile playerProfile = core.getStorage().loadProfile(targetPlayer);
//existing player is already cracked
if (playerProfile.isSaved() && !playerProfile.isOnlinemodePreferred()) {
if (playerProfile.isExistingPlayer() && !playerProfile.isOnlinemodePreferred()) {
sendMessage("not-premium");
return;
}