Minor cleanup using inspections + Https

* Use https for maven repositories if possible
* Fix typos
* Merge ProtocolLib listeners into one class
* Upgrade maven plugins and dependencies
This commit is contained in:
games647
2017-07-22 08:27:55 +02:00
parent 6595dc6ac0
commit 033333e35c
27 changed files with 93 additions and 199 deletions

View File

@ -110,7 +110,7 @@ Put your stats id from the BungeeCord config into this file
2. Server -> Client: Okay. I'm in online mode so here is my public key for encryption and my serverid
3. Client -> Mojang: I'm player "xyz". I want to join a server with that serverid
4. Mojang -> Client: Session data checked. You can continue
5. Client -> Server: I received a successful response from Mojang. Heres our shared secret key
5. Client -> Server: I received a successful response from Mojang. Here our shared secret key
6. Server -> Mojang: Does the player "xyz" with this shared secret key has a valid account to join me?
7. Mojang -> Server: Yes, the player has the following additionally properties (UUID, Skin)
8. Client and Server: encrypt all following communication packet
@ -158,7 +158,7 @@ of a cracked player that has the same username. The player have to proof first t
to a paid account but if we request a online mode login from a cracked player (who uses a username from
a paid account), the player will disconnect with the reason "bad login" or "Invalid session". There is no way to change
that message on the server side (without client modifications), because it's a connection between the Client and the
Sessionserver.
sessionserver.
3. If a premium player would skip registration too, a player of a cracked account could later still register the
account and would claim and steal the account from the premium player. Because commands cannot be invoked unless the
player has a account or is logged in, protects this method also premium players

View File

@ -37,7 +37,7 @@
<!--Authme Reloaded-->
<repository>
<id>xephi-repo</id>
<url>http://ci.xephi.fr/plugin/repository/everything/</url>
<url>https://ci.xephi.fr/plugin/repository/everything/</url>
</repository>
<!--xAuth-->

View File

@ -28,7 +28,7 @@ public class BukkitLoginSession extends LoginSession {
this.verifyToken = ArrayUtils.clone(verifyToken);
}
//available for bungeecord
//available for BungeeCord
public BukkitLoginSession(String username, boolean registered) {
this(username, "", ArrayUtils.EMPTY_BYTE_ARRAY, registered, null);
}
@ -41,7 +41,7 @@ public class BukkitLoginSession extends LoginSession {
/**
* Gets the random generated server id. This makes sure the request sent from the client is just for this server.
*
* See this for details http://www.sk89q.com/2011/09/minecraft-name-spoofing-exploit/
* See this for details http://www.sk89q.com/2011/09/Minecraft-name-spoofing-exploit/
*
* Empty if it's a BungeeCord connection
*

View File

@ -8,8 +8,6 @@ import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.stream.Stream;
import javax.crypto.BadPaddingException;
@ -41,7 +39,7 @@ public class EncryptionUtil {
}
}
public static byte[] getServerIdHash(String serverId, PublicKey publicKey, SecretKey secretKey) {
public static byte[] getServerIdHash(String serverId, Key publicKey, Key secretKey) {
return digestOperation("SHA-1"
, new byte[][]{serverId.getBytes(Charsets.ISO_8859_1), secretKey.getEncoded(), publicKey.getEncoded()});
}
@ -72,7 +70,7 @@ public class EncryptionUtil {
// return null;
// }
public static SecretKey decryptSharedKey(PrivateKey privateKey, byte[] encryptedSharedKey) {
public static SecretKey decryptSharedKey(Key privateKey, byte[] encryptedSharedKey) {
return new SecretKeySpec(decryptData(privateKey, encryptedSharedKey), "AES");
}

View File

@ -5,9 +5,8 @@ import com.github.games647.fastlogin.bukkit.commands.ImportCommand;
import com.github.games647.fastlogin.bukkit.commands.PremiumCommand;
import com.github.games647.fastlogin.bukkit.listener.BukkitJoinListener;
import com.github.games647.fastlogin.bukkit.listener.BungeeCordListener;
import com.github.games647.fastlogin.bukkit.listener.protocollib.EncryptionPacketListener;
import com.github.games647.fastlogin.bukkit.listener.protocollib.LoginSkinApplyListener;
import com.github.games647.fastlogin.bukkit.listener.protocollib.StartPacketListener;
import com.github.games647.fastlogin.bukkit.listener.protocollib.ProtocolLibListener;
import com.github.games647.fastlogin.bukkit.listener.protocolsupport.ProtocolSupportListener;
import com.github.games647.fastlogin.bukkit.tasks.DelayedAuthHook;
import com.github.games647.fastlogin.core.shared.FastLoginCore;
@ -32,14 +31,13 @@ import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.messaging.PluginMessageRecipient;
/**
* This plugin checks if a player has a paid account and if so tries to skip offline mode authentication.
*/
public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<CommandSender> {
private static final int WORKER_THREADS = 3;
//provide a immutable key pair to be thread safe | used for encrypting and decrypting traffic
private final KeyPair keyPair = EncryptionUtil.generateKeyPair();
@ -90,8 +88,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
//they will be created with a static builder, because otherwise it will throw a
//java.lang.NoClassDefFoundError: com/comphenix/protocol/events/PacketListener if ProtocolSupport was
//only found
StartPacketListener.register(this, WORKER_THREADS);
EncryptionPacketListener.register(this, WORKER_THREADS);
ProtocolLibListener.register(this);
getServer().getPluginManager().registerEvents(new LoginSkinApplyListener(this), this);
} else {
@ -185,7 +182,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
}
}
private void notifiyBungeeCord(Player sender, String target, boolean activate, boolean isPlayer) {
private void notifiyBungeeCord(PluginMessageRecipient sender, String target, boolean activate, boolean isPlayer) {
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
if (activate) {
dataOutput.writeUTF("ON");

View File

@ -33,7 +33,7 @@ public class MojangApiBukkit extends MojangApiConnector {
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = reader.readLine();
if (line != null && !line.equals("null")) {
if (line != null && !"null".equals(line)) {
//validate parsing
//http://wiki.vg/Protocol_Encryption#Server
JSONObject userData = (JSONObject) JSONValue.parseWithException(line);
@ -44,7 +44,7 @@ public class MojangApiBukkit extends MojangApiConnector {
JSONObject skinProperty = (JSONObject) properties.get(0);
String propertyName = (String) skinProperty.get("name");
if (propertyName.equals("textures")) {
if ("textures".equals(propertyName)) {
String skinValue = (String) skinProperty.get("value");
String signature = (String) skinProperty.get("signature");
playerSession.setSkin(skinValue, signature);

View File

@ -24,7 +24,7 @@ public class PremiumPlaceholder extends PlaceholderHook {
return "unknown";
}
if (metadata.size() > 0) {
if (!metadata.isEmpty()) {
return "premium";
} else {
return "cracked";

View File

@ -8,6 +8,7 @@ import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.royaldev.royalauth.AuthPlayer;
import org.royaldev.royalauth.Config;
import org.royaldev.royalauth.RoyalAuth;
@ -21,7 +22,7 @@ import org.royaldev.royalauth.RoyalAuth;
*/
public class RoyalAuthHook implements AuthPlugin<Player> {
private final RoyalAuth royalAuthPlugin = (RoyalAuth) Bukkit.getPluginManager().getPlugin("RoyalAuth");
private final Plugin royalAuthPlugin = (RoyalAuth) Bukkit.getPluginManager().getPlugin("RoyalAuth");
@Override
public boolean forceLogin(Player player) {

View File

@ -53,7 +53,7 @@ public class UltraAuthHook implements AuthPlugin<Player> {
public boolean forceRegister(Player player, String password) {
UltraAuthAPI.setPlayerPasswordOnline(player, password);
if (PlayerManager.getInstance().checkPlayerPassword(player, password)) {
//the register method silents any excpetion so check if our entry was saved
//the register method silents any exception so check if our entry was saved
return forceLogin(player);
}

View File

@ -66,10 +66,9 @@ public class xAuthHook implements AuthPlugin<Player> {
if (xAuthPlayer != null) {
//this should run async because the plugin executes a sql query, but the method
//accesses non thread-safe collections :(
boolean registerSuccess = xAuthPlugin.getAuthClass(xAuthPlayer)
.adminRegister(player.getName(), password, null);
return registerSuccess;
return xAuthPlugin.getAuthClass(xAuthPlayer)
.adminRegister(player.getName(), password, null);
}
return false;

View File

@ -40,7 +40,7 @@ public class BukkitJoinListener implements Listener {
if (!plugin.isBungeeCord()) {
//Wait before auth plugin and we received a message from BungeeCord initializes the player
ForceLoginTask forceLoginTask = new ForceLoginTask(plugin.getCore(), player);
Runnable forceLoginTask = new ForceLoginTask(plugin.getCore(), player);
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, forceLoginTask, DELAY_LOGIN);
}
}

View File

@ -1,72 +0,0 @@
package com.github.games647.fastlogin.bukkit.listener.protocollib;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
/**
* Handles incoming encryption responses from connecting clients.
* It prevents them from reaching the server because that cannot handle
* it in offline mode.
*
* Moreover this manages a started premium check from
* this plugin. So check if all data is correct and we can prove him as a
* owner of a paid minecraft account.
*
* Receiving packet information:
* http://wiki.vg/Protocol#Encryption_Response
*
* sharedSecret=encrypted byte array
* verify token=encrypted byte array
*/
public class EncryptionPacketListener extends PacketAdapter {
//hides the inherit Plugin plugin field, but we need this type
private final FastLoginBukkit plugin;
public EncryptionPacketListener(FastLoginBukkit plugin) {
//run async in order to not block the server, because we make api calls to Mojang
super(params(plugin, PacketType.Login.Client.ENCRYPTION_BEGIN).optionAsync());
this.plugin = plugin;
}
public static void register(FastLoginBukkit plugin, int workerThreads) {
ProtocolLibrary.getProtocolManager().getAsynchronousManager()
.registerAsyncHandler(new EncryptionPacketListener(plugin)).start(workerThreads);
}
/**
* C->S : Handshake State=2
* C->S : Login Start
* S->C : Encryption Key Request
* (Client Auth)
* C->S : Encryption Key Response
* (Server Auth, Both enable encryption)
* S->C : Login Success (*)
*
* On offline logins is Login Start followed by Login Success
*
* Minecraft Server implementation
* https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/LoginListener.java#L180
*/
@Override
public void onPacketReceiving(PacketEvent packetEvent) {
if (packetEvent.isCancelled()) {
return;
}
Player sender = packetEvent.getPlayer();
byte[] sharedSecret = packetEvent.getPacket().getByteArrays().read(0);
packetEvent.getAsyncMarker().incrementProcessingDelay();
VerifyResponseTask verifyTask = new VerifyResponseTask(plugin, packetEvent, sender, sharedSecret);
Bukkit.getScheduler().runTaskAsynchronously(plugin, verifyTask);
}
}

View File

@ -1,6 +1,7 @@
package com.github.games647.fastlogin.bukkit.listener.protocollib;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Login.Client;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
@ -13,57 +14,56 @@ import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
/**
* Handles incoming start packets from connecting clients. It
* checks if we can start checking if the player is premium and
* start a request to the client that it should start online mode
* login.
*
* Receiving packet information:
* http://wiki.vg/Protocol#Login_Start
*
* String=Username
*/
public class StartPacketListener extends PacketAdapter {
public class ProtocolLibListener extends PacketAdapter {
private static final int WORKER_THREADS = 3;
//hides the inherit Plugin plugin field, but we need a more detailed type than just Plugin
private final FastLoginBukkit plugin;
//just create a new once on plugin enable. This used for verify token generation
private final Random random = new Random();
public StartPacketListener(FastLoginBukkit plugin) {
public ProtocolLibListener(FastLoginBukkit plugin) {
//run async in order to not block the server, because we are making api calls to Mojang
super(params(plugin, PacketType.Login.Client.START).optionAsync());
super(params().plugin(plugin)
.types(PacketType.Login.Client.START)
.types(PacketType.Login.Client.ENCRYPTION_BEGIN)
.optionAsync());
this.plugin = plugin;
}
public static void register(FastLoginBukkit plugin, int workerThreads) {
public static void register(FastLoginBukkit plugin) {
ProtocolLibrary.getProtocolManager().getAsynchronousManager()
.registerAsyncHandler(new StartPacketListener(plugin)).start(workerThreads);
.registerAsyncHandler(new ProtocolLibListener(plugin))
.start(WORKER_THREADS);
}
/**
* C->S : Handshake State=2
* C->S : Login Start
* S->C : Encryption Key Request
* (Client Auth)
* C->S : Encryption Key Response
* (Server Auth, Both enable encryption)
* S->C : Login Success (*)
*
* On offline logins is Login Start followed by Login Success
*/
@Override
public void onPacketReceiving(PacketEvent packetEvent) {
if (packetEvent.isCancelled()
|| plugin.getCore().getAuthPluginHook()== null || !plugin.isServerFullyStarted()) {
|| plugin.getCore().getAuthPluginHook()== null
|| !plugin.isServerFullyStarted()) {
return;
}
Player player = packetEvent.getPlayer();
Player sender = packetEvent.getPlayer();
PacketType packetType = packetEvent.getPacketType();
if (packetType == Client.START) {
onLogin(packetEvent, sender);
} else {
onEncryptionBegin(packetEvent, sender);
}
}
private void onEncryptionBegin(PacketEvent packetEvent, Player sender) {
byte[] sharedSecret = packetEvent.getPacket().getByteArrays().read(0);
packetEvent.getAsyncMarker().incrementProcessingDelay();
Runnable verifyTask = new VerifyResponseTask(plugin, packetEvent, sender, sharedSecret);
Bukkit.getScheduler().runTaskAsynchronously(plugin, verifyTask);
}
private void onLogin(PacketEvent packetEvent, Player player) {
//this includes ip:port. Should be unique for an incoming login request with a timeout of 2 minutes
String sessionKey = player.getAddress().toString();
@ -77,7 +77,7 @@ public class StartPacketListener extends PacketAdapter {
plugin.getLogger().log(Level.FINER, "Player {0} with {1} connecting", new Object[]{sessionKey, username});
packetEvent.getAsyncMarker().incrementProcessingDelay();
NameCheckTask nameCheckTask = new NameCheckTask(plugin, packetEvent, random, player, username);
Runnable nameCheckTask = new NameCheckTask(plugin, packetEvent, random, player, username);
Bukkit.getScheduler().runTaskAsynchronously(plugin, nameCheckTask);
}
}

View File

@ -17,6 +17,7 @@ import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.security.Key;
import java.security.PrivateKey;
import java.util.Arrays;
import java.util.UUID;
@ -47,7 +48,7 @@ public class VerifyResponseTask implements Runnable {
try {
BukkitLoginSession session = plugin.getLoginSessions().get(fromPlayer.getAddress().toString());
if (session == null) {
disconnect(plugin.getCore().getMessage("invalid-requst"), true
disconnect(plugin.getCore().getMessage("invalid-request"), true
, "Player {0} tried to send encryption response at invalid state", fromPlayer.getAddress());
} else {
verifyResponse(session);
@ -106,7 +107,7 @@ public class VerifyResponseTask implements Runnable {
}
}
private boolean checkVerifyToken(BukkitLoginSession session, PrivateKey privateKey) {
private boolean checkVerifyToken(BukkitLoginSession session, Key privateKey) {
byte[] requestVerify = session.getVerifyToken();
//encrypted verify token
byte[] responseVerify = packetEvent.getPacket().getByteArrays().read(1);

View File

@ -1,10 +1,10 @@
# project informations for Bukkit in order to register our plugin with all it components
# project data for Bukkit in order to register our plugin with all it components
# ${-} are variables from Maven (pom.xml) which will be replaced after the build
name: ${project.parent.name}
version: ${project.version}-git${git.commit.id}
main: ${project.groupId}.${project.artifactId}.${project.name}
# meta informations for plugin managers
# meta data for plugin managers
authors: [games647, 'https://github.com/games647/FastLogin/graphs/contributors']
description: |
${project.description}
@ -55,4 +55,4 @@ permissions:
${project.artifactId}.command.cracked.other:
description: 'Label others as cracked'
children:
${project.artifactId}.command.cracked: true
${project.artifactId}.command.cracked: true

View File

@ -19,8 +19,8 @@
<repositories>
<!--BungeeCord with also the part outside the API-->
<repository>
<id>bungee-repo</id>
<url>https://repo.extension.ws/content/repositories/snapshots/</url>
<id>luck-repo</id>
<url>https://ci.lucko.me/plugin/repository/everything</url>
</repository>
<repository>
@ -38,9 +38,9 @@
</dependency>
<dependency>
<groupId>tc.oc</groupId>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-proxy</artifactId>
<version>1.11-SNAPSHOT</version>
<version>1.12-SNAPSHOT</version>
<scope>provided</scope>
</dependency>

View File

@ -29,7 +29,7 @@ public class MojangApiBungee extends MojangApiConnector {
if ("null".equals(id)) {
return null;
}
return id;
}

View File

@ -48,7 +48,7 @@ public class PlayerConnectionListener implements Listener {
preLoginEvent.registerIntent(plugin);
PendingConnection connection = preLoginEvent.getConnection();
AsyncPremiumCheck asyncPremiumCheck = new AsyncPremiumCheck(plugin, preLoginEvent, connection);
Runnable asyncPremiumCheck = new AsyncPremiumCheck(plugin, preLoginEvent, connection);
ProxyServer.getInstance().getScheduler().runAsync(plugin, asyncPremiumCheck);
}
@ -101,7 +101,7 @@ public class PlayerConnectionListener implements Listener {
ProxiedPlayer player = serverConnectedEvent.getPlayer();
Server server = serverConnectedEvent.getServer();
ForceLoginTask loginTask = new ForceLoginTask(plugin.getCore(), player, server);
Runnable loginTask = new ForceLoginTask(plugin.getCore(), player, server);
ProxyServer.getInstance().getScheduler().runAsync(plugin, loginTask);
}

View File

@ -68,13 +68,13 @@ public class PluginMessageListener implements Listener {
}
core.getPendingConfirms().remove(forPlayer.getUniqueId());
AsyncToggleMessage task = new AsyncToggleMessage(core, forPlayer, playerName, true, isPlayerSender);
Runnable task = new AsyncToggleMessage(core, forPlayer, playerName, true, isPlayerSender);
ProxyServer.getInstance().getScheduler().runAsync(plugin, task);
} else if ("OFF".equals(subchannel)) {
String playerName = dataInput.readUTF();
boolean isPlayerSender = dataInput.readBoolean();
AsyncToggleMessage task = new AsyncToggleMessage(core, forPlayer, playerName, false, isPlayerSender);
Runnable task = new AsyncToggleMessage(core, forPlayer, playerName, false, isPlayerSender);
ProxyServer.getInstance().getScheduler().runAsync(plugin, task);
}
}

View File

@ -1,4 +1,4 @@
# project informations for BungeeCord
# project data for BungeeCord
# This file will be prioritised over plugin.yml which can be also used for Bungee
# This make it easy to combine BungeeCord and Bukkit support in one plugin
name: ${project.parent.name}
@ -13,4 +13,4 @@ softDepends:
- BungeeAuth
description: |
${project.description}
${project.description}

View File

@ -15,6 +15,8 @@ import java.util.UUID;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Level;
import javax.sql.DataSource;
public class AuthStorage {
private static final String PREMIUM_TABLE = "premium";
@ -63,7 +65,7 @@ public class AuthStorage {
this.dataSource = new HikariDataSource(databaseConfig);
}
public HikariDataSource getDataSource() {
public DataSource getDataSource() {
return dataSource;
}
@ -83,7 +85,7 @@ public class AuthStorage {
+ "LastLogin TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "
//the premium shouldn't steal the cracked account by changing the name
+ "UNIQUE (Name) "
+ ")";
+ ')';
if (dataSource.getJdbcUrl().contains("sqlite")) {
createDataStmt = createDataStmt.replace("AUTO_INCREMENT", "AUTOINCREMENT");
@ -142,11 +144,9 @@ public class AuthStorage {
boolean premium = resultSet.getBoolean(4);
String lastIp = resultSet.getString(5);
long lastLogin = resultSet.getTimestamp(6).getTime();
PlayerProfile playerProfile = new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
return playerProfile;
return new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
} else {
PlayerProfile crackedProfile = new PlayerProfile(null, name, false, "");
return crackedProfile;
return new PlayerProfile(null, name, false, "");
}
} catch (SQLException sqlEx) {
core.getPlugin().getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
@ -176,8 +176,7 @@ public class AuthStorage {
boolean premium = resultSet.getBoolean(4);
String lastIp = resultSet.getString(5);
long lastLogin = resultSet.getTimestamp(6).getTime();
PlayerProfile playerProfile = new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
return playerProfile;
return new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
}
} catch (SQLException sqlEx) {
core.getPlugin().getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);

View File

@ -54,7 +54,7 @@ public class CompatibleCacheBuilder<K, V> {
* @param concurrencyLevel New concurrency level
* @return This for chaining
*
* @throws IllegalArgumentException if {@code concurrencyLevel} is nonpositive
* @throws IllegalArgumentException if {@code concurrencyLevel} is non-positive
* @throws IllegalStateException if a concurrency level was already set
*/
public CompatibleCacheBuilder<K, V> concurrencyLevel(int concurrencyLevel) {
@ -76,7 +76,7 @@ public class CompatibleCacheBuilder<K, V> {
* <p>
* Expired entries may be counted by {@link com.google.common.cache.Cache#size Cache.size()}, but will never be
* visible to read or write operations. Expired entries are currently cleaned up during write operations, or during
* occasional read operations in the absense of writes; though this behavior may change in the future.
* occasional read operations in the absence of writes; though this behavior may change in the future.
*
* @param duration the length of time after an entry is last accessed that it should be automatically removed
* @param unit the unit that {@code duration} is expressed in
@ -102,7 +102,7 @@ public class CompatibleCacheBuilder<K, V> {
* <p>
* Expired entries may be counted by {@link com.google.common.cache.Cache#size Cache.size()}, but will never be
* visible to read or write operations. Expired entries are currently cleaned up during write operations, or during
* occasional read operations in the absense of writes; though this behavior may change in the future.
* occasional read operations in the absence of writes; though this behavior may change in the future.
*
* @param duration the length of time after an entry is created that it should be automatically removed
* @param unit the unit that {@code duration} is expressed in
@ -284,7 +284,7 @@ public class CompatibleCacheBuilder<K, V> {
*/
@SuppressWarnings("unchecked")
public <K1 extends K, V1 extends V> ConcurrentMap<K1, V1> build(CacheLoader<? super K1, V1> loader) {
Object cache = null;
Object cache;
if (BUILD_METHOD == null) {
try {

View File

@ -1,5 +1,6 @@
package com.github.games647.fastlogin.core.hooks;
@FunctionalInterface
public interface PasswordGenerator<P> {
String getRandomPassword(P player);

View File

@ -21,6 +21,7 @@ import java.nio.file.Path;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@ -60,10 +61,10 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
}
return UUID.fromString(withoutDashes.substring(0, 8)
+ "-" + withoutDashes.substring(8, 12)
+ "-" + withoutDashes.substring(12, 16)
+ "-" + withoutDashes.substring(16, 20)
+ "-" + withoutDashes.substring(20, 32));
+ '-' + withoutDashes.substring(8, 12)
+ '-' + withoutDashes.substring(12, 16)
+ '-' + withoutDashes.substring(16, 20)
+ '-' + withoutDashes.substring(20, 32));
}
protected final Map<String, String> localeMessages = new ConcurrentHashMap<>();
@ -198,7 +199,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
} else {
Class.forName("com.mysql.jdbc.Driver");
String jdbcUrl = "jdbc:mysql://" + host + "/" + database;
String jdbcUrl = "jdbc:mysql://" + host + '/' + database;
Connection con = DriverManager.getConnection(jdbcUrl, username, pass);
importer.importData(con, storage.getDataSource(), storage);
return true;
@ -228,7 +229,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
return pendingLogins;
}
public Set<UUID> getPendingConfirms() {
public Collection<UUID> getPendingConfirms() {
return pendingConfirms;
}

View File

@ -10,7 +10,7 @@ import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Collection;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
@ -43,7 +43,7 @@ public abstract class MojangApiConnector {
protected final Logger logger;
public MojangApiConnector(Logger logger, List<String> localAddresses, int rateLimit) {
public MojangApiConnector(Logger logger, Collection<String> localAddresses, int rateLimit) {
this.logger = logger;
if (rateLimit > 600) {
@ -95,7 +95,7 @@ public abstract class MojangApiConnector {
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = reader.readLine();
if (!line.equals("null")) {
if (!"null".equals(line)) {
return FastLoginCore.parseId(getUUIDFromJson(line));
}
} else if (connection.getResponseCode() == RATE_LIMIT_CODE) {

24
pom.xml
View File

@ -29,17 +29,6 @@
<module>universal</module>
</modules>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/games647/FastLogin/issues</url>
</issueManagement>
<scm>
<url>https://github.com/games647/FastLogin</url>
<connection>scm:git:git://github.com/games647/FastLogin.git</connection>
<developerConnection>scm:git:ssh://git@github.com:games647/FastLogin.git</developerConnection>
</scm>
<build>
<defaultGoal>install</defaultGoal>
<!--Just use the project name to replace an old version of the plugin if the user does only copy-paste-->
@ -53,15 +42,13 @@
<configuration>
<source>1.8</source>
<target>1.8</target>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>2.2.1</version>
<version>2.2.2</version>
<configuration>
<failOnNoGitDirectory>false</failOnNoGitDirectory>
</configuration>
@ -82,15 +69,6 @@
<!--Replace variables-->
<filtering>true</filtering>
</resource>
<!--Add the license to jar in order to see it in the final jar-->
<resource>
<!--Parent folder-->
<directory>${basedir}/..</directory>
<includes>
<include>LICENSE</include>
</includes>
</resource>
</resources>
</build>
</project>

View File

@ -22,7 +22,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<version>3.0.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>false</shadedArtifactAttached>
@ -43,15 +43,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<outputDirectory>${outputDir}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>