mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-07-30 02:37:34 +02:00
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:
@ -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
|
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
|
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
|
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?
|
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)
|
7. Mojang -> Server: Yes, the player has the following additionally properties (UUID, Skin)
|
||||||
8. Client and Server: encrypt all following communication packet
|
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
|
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
|
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
|
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
|
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
|
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
|
player has a account or is logged in, protects this method also premium players
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
<!--Authme Reloaded-->
|
<!--Authme Reloaded-->
|
||||||
<repository>
|
<repository>
|
||||||
<id>xephi-repo</id>
|
<id>xephi-repo</id>
|
||||||
<url>http://ci.xephi.fr/plugin/repository/everything/</url>
|
<url>https://ci.xephi.fr/plugin/repository/everything/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
<!--xAuth-->
|
<!--xAuth-->
|
||||||
|
@ -28,7 +28,7 @@ public class BukkitLoginSession extends LoginSession {
|
|||||||
this.verifyToken = ArrayUtils.clone(verifyToken);
|
this.verifyToken = ArrayUtils.clone(verifyToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
//available for bungeecord
|
//available for BungeeCord
|
||||||
public BukkitLoginSession(String username, boolean registered) {
|
public BukkitLoginSession(String username, boolean registered) {
|
||||||
this(username, "", ArrayUtils.EMPTY_BYTE_ARRAY, registered, null);
|
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.
|
* 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
|
* Empty if it's a BungeeCord connection
|
||||||
*
|
*
|
||||||
|
@ -8,8 +8,6 @@ import java.security.KeyPair;
|
|||||||
import java.security.KeyPairGenerator;
|
import java.security.KeyPairGenerator;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
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"
|
return digestOperation("SHA-1"
|
||||||
, new byte[][]{serverId.getBytes(Charsets.ISO_8859_1), secretKey.getEncoded(), publicKey.getEncoded()});
|
, new byte[][]{serverId.getBytes(Charsets.ISO_8859_1), secretKey.getEncoded(), publicKey.getEncoded()});
|
||||||
}
|
}
|
||||||
@ -72,7 +70,7 @@ public class EncryptionUtil {
|
|||||||
// return null;
|
// 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");
|
return new SecretKeySpec(decryptData(privateKey, encryptedSharedKey), "AES");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.commands.PremiumCommand;
|
||||||
import com.github.games647.fastlogin.bukkit.listener.BukkitJoinListener;
|
import com.github.games647.fastlogin.bukkit.listener.BukkitJoinListener;
|
||||||
import com.github.games647.fastlogin.bukkit.listener.BungeeCordListener;
|
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.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.listener.protocolsupport.ProtocolSupportListener;
|
||||||
import com.github.games647.fastlogin.bukkit.tasks.DelayedAuthHook;
|
import com.github.games647.fastlogin.bukkit.tasks.DelayedAuthHook;
|
||||||
import com.github.games647.fastlogin.core.shared.FastLoginCore;
|
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.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
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.
|
* 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> {
|
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
|
//provide a immutable key pair to be thread safe | used for encrypting and decrypting traffic
|
||||||
private final KeyPair keyPair = EncryptionUtil.generateKeyPair();
|
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
|
//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
|
//java.lang.NoClassDefFoundError: com/comphenix/protocol/events/PacketListener if ProtocolSupport was
|
||||||
//only found
|
//only found
|
||||||
StartPacketListener.register(this, WORKER_THREADS);
|
ProtocolLibListener.register(this);
|
||||||
EncryptionPacketListener.register(this, WORKER_THREADS);
|
|
||||||
|
|
||||||
getServer().getPluginManager().registerEvents(new LoginSkinApplyListener(this), this);
|
getServer().getPluginManager().registerEvents(new LoginSkinApplyListener(this), this);
|
||||||
} else {
|
} 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();
|
ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput();
|
||||||
if (activate) {
|
if (activate) {
|
||||||
dataOutput.writeUTF("ON");
|
dataOutput.writeUTF("ON");
|
||||||
|
@ -33,7 +33,7 @@ public class MojangApiBukkit extends MojangApiConnector {
|
|||||||
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||||
String line = reader.readLine();
|
String line = reader.readLine();
|
||||||
if (line != null && !line.equals("null")) {
|
if (line != null && !"null".equals(line)) {
|
||||||
//validate parsing
|
//validate parsing
|
||||||
//http://wiki.vg/Protocol_Encryption#Server
|
//http://wiki.vg/Protocol_Encryption#Server
|
||||||
JSONObject userData = (JSONObject) JSONValue.parseWithException(line);
|
JSONObject userData = (JSONObject) JSONValue.parseWithException(line);
|
||||||
@ -44,7 +44,7 @@ public class MojangApiBukkit extends MojangApiConnector {
|
|||||||
JSONObject skinProperty = (JSONObject) properties.get(0);
|
JSONObject skinProperty = (JSONObject) properties.get(0);
|
||||||
|
|
||||||
String propertyName = (String) skinProperty.get("name");
|
String propertyName = (String) skinProperty.get("name");
|
||||||
if (propertyName.equals("textures")) {
|
if ("textures".equals(propertyName)) {
|
||||||
String skinValue = (String) skinProperty.get("value");
|
String skinValue = (String) skinProperty.get("value");
|
||||||
String signature = (String) skinProperty.get("signature");
|
String signature = (String) skinProperty.get("signature");
|
||||||
playerSession.setSkin(skinValue, signature);
|
playerSession.setSkin(skinValue, signature);
|
||||||
|
@ -24,7 +24,7 @@ public class PremiumPlaceholder extends PlaceholderHook {
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metadata.size() > 0) {
|
if (!metadata.isEmpty()) {
|
||||||
return "premium";
|
return "premium";
|
||||||
} else {
|
} else {
|
||||||
return "cracked";
|
return "cracked";
|
||||||
|
@ -8,6 +8,7 @@ import java.util.logging.Level;
|
|||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.royaldev.royalauth.AuthPlayer;
|
import org.royaldev.royalauth.AuthPlayer;
|
||||||
import org.royaldev.royalauth.Config;
|
import org.royaldev.royalauth.Config;
|
||||||
import org.royaldev.royalauth.RoyalAuth;
|
import org.royaldev.royalauth.RoyalAuth;
|
||||||
@ -21,7 +22,7 @@ import org.royaldev.royalauth.RoyalAuth;
|
|||||||
*/
|
*/
|
||||||
public class RoyalAuthHook implements AuthPlugin<Player> {
|
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
|
@Override
|
||||||
public boolean forceLogin(Player player) {
|
public boolean forceLogin(Player player) {
|
||||||
|
@ -53,7 +53,7 @@ public class UltraAuthHook implements AuthPlugin<Player> {
|
|||||||
public boolean forceRegister(Player player, String password) {
|
public boolean forceRegister(Player player, String password) {
|
||||||
UltraAuthAPI.setPlayerPasswordOnline(player, password);
|
UltraAuthAPI.setPlayerPasswordOnline(player, password);
|
||||||
if (PlayerManager.getInstance().checkPlayerPassword(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);
|
return forceLogin(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,10 +66,9 @@ public class xAuthHook implements AuthPlugin<Player> {
|
|||||||
if (xAuthPlayer != null) {
|
if (xAuthPlayer != null) {
|
||||||
//this should run async because the plugin executes a sql query, but the method
|
//this should run async because the plugin executes a sql query, but the method
|
||||||
//accesses non thread-safe collections :(
|
//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;
|
return false;
|
||||||
|
@ -40,7 +40,7 @@ public class BukkitJoinListener implements Listener {
|
|||||||
|
|
||||||
if (!plugin.isBungeeCord()) {
|
if (!plugin.isBungeeCord()) {
|
||||||
//Wait before auth plugin and we received a message from BungeeCord initializes the player
|
//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);
|
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, forceLoginTask, DELAY_LOGIN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
package com.github.games647.fastlogin.bukkit.listener.protocollib;
|
package com.github.games647.fastlogin.bukkit.listener.protocollib;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.PacketType.Login.Client;
|
||||||
import com.comphenix.protocol.ProtocolLibrary;
|
import com.comphenix.protocol.ProtocolLibrary;
|
||||||
import com.comphenix.protocol.events.PacketAdapter;
|
import com.comphenix.protocol.events.PacketAdapter;
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
@ -13,57 +14,56 @@ import java.util.logging.Level;
|
|||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
/**
|
public class ProtocolLibListener extends PacketAdapter {
|
||||||
* Handles incoming start packets from connecting clients. It
|
|
||||||
* checks if we can start checking if the player is premium and
|
private static final int WORKER_THREADS = 3;
|
||||||
* 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 {
|
|
||||||
|
|
||||||
//hides the inherit Plugin plugin field, but we need a more detailed type than just Plugin
|
|
||||||
private final FastLoginBukkit plugin;
|
private final FastLoginBukkit plugin;
|
||||||
|
|
||||||
//just create a new once on plugin enable. This used for verify token generation
|
//just create a new once on plugin enable. This used for verify token generation
|
||||||
private final Random random = new Random();
|
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
|
//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;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void register(FastLoginBukkit plugin, int workerThreads) {
|
public static void register(FastLoginBukkit plugin) {
|
||||||
ProtocolLibrary.getProtocolManager().getAsynchronousManager()
|
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
|
@Override
|
||||||
public void onPacketReceiving(PacketEvent packetEvent) {
|
public void onPacketReceiving(PacketEvent packetEvent) {
|
||||||
if (packetEvent.isCancelled()
|
if (packetEvent.isCancelled()
|
||||||
|| plugin.getCore().getAuthPluginHook()== null || !plugin.isServerFullyStarted()) {
|
|| plugin.getCore().getAuthPluginHook()== null
|
||||||
|
|| !plugin.isServerFullyStarted()) {
|
||||||
return;
|
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
|
//this includes ip:port. Should be unique for an incoming login request with a timeout of 2 minutes
|
||||||
String sessionKey = player.getAddress().toString();
|
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});
|
plugin.getLogger().log(Level.FINER, "Player {0} with {1} connecting", new Object[]{sessionKey, username});
|
||||||
|
|
||||||
packetEvent.getAsyncMarker().incrementProcessingDelay();
|
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);
|
Bukkit.getScheduler().runTaskAsynchronously(plugin, nameCheckTask);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,6 +17,7 @@ import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.security.Key;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -47,7 +48,7 @@ public class VerifyResponseTask implements Runnable {
|
|||||||
try {
|
try {
|
||||||
BukkitLoginSession session = plugin.getLoginSessions().get(fromPlayer.getAddress().toString());
|
BukkitLoginSession session = plugin.getLoginSessions().get(fromPlayer.getAddress().toString());
|
||||||
if (session == null) {
|
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());
|
, "Player {0} tried to send encryption response at invalid state", fromPlayer.getAddress());
|
||||||
} else {
|
} else {
|
||||||
verifyResponse(session);
|
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();
|
byte[] requestVerify = session.getVerifyToken();
|
||||||
//encrypted verify token
|
//encrypted verify token
|
||||||
byte[] responseVerify = packetEvent.getPacket().getByteArrays().read(1);
|
byte[] responseVerify = packetEvent.getPacket().getByteArrays().read(1);
|
||||||
|
@ -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
|
# ${-} are variables from Maven (pom.xml) which will be replaced after the build
|
||||||
name: ${project.parent.name}
|
name: ${project.parent.name}
|
||||||
version: ${project.version}-git${git.commit.id}
|
version: ${project.version}-git${git.commit.id}
|
||||||
main: ${project.groupId}.${project.artifactId}.${project.name}
|
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']
|
authors: [games647, 'https://github.com/games647/FastLogin/graphs/contributors']
|
||||||
description: |
|
description: |
|
||||||
${project.description}
|
${project.description}
|
||||||
@ -55,4 +55,4 @@ permissions:
|
|||||||
${project.artifactId}.command.cracked.other:
|
${project.artifactId}.command.cracked.other:
|
||||||
description: 'Label others as cracked'
|
description: 'Label others as cracked'
|
||||||
children:
|
children:
|
||||||
${project.artifactId}.command.cracked: true
|
${project.artifactId}.command.cracked: true
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
<repositories>
|
<repositories>
|
||||||
<!--BungeeCord with also the part outside the API-->
|
<!--BungeeCord with also the part outside the API-->
|
||||||
<repository>
|
<repository>
|
||||||
<id>bungee-repo</id>
|
<id>luck-repo</id>
|
||||||
<url>https://repo.extension.ws/content/repositories/snapshots/</url>
|
<url>https://ci.lucko.me/plugin/repository/everything</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
@ -38,9 +38,9 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>tc.oc</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-proxy</artifactId>
|
<artifactId>bungeecord-proxy</artifactId>
|
||||||
<version>1.11-SNAPSHOT</version>
|
<version>1.12-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ public class MojangApiBungee extends MojangApiConnector {
|
|||||||
if ("null".equals(id)) {
|
if ("null".equals(id)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ public class PlayerConnectionListener implements Listener {
|
|||||||
preLoginEvent.registerIntent(plugin);
|
preLoginEvent.registerIntent(plugin);
|
||||||
|
|
||||||
PendingConnection connection = preLoginEvent.getConnection();
|
PendingConnection connection = preLoginEvent.getConnection();
|
||||||
AsyncPremiumCheck asyncPremiumCheck = new AsyncPremiumCheck(plugin, preLoginEvent, connection);
|
Runnable asyncPremiumCheck = new AsyncPremiumCheck(plugin, preLoginEvent, connection);
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(plugin, asyncPremiumCheck);
|
ProxyServer.getInstance().getScheduler().runAsync(plugin, asyncPremiumCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ public class PlayerConnectionListener implements Listener {
|
|||||||
ProxiedPlayer player = serverConnectedEvent.getPlayer();
|
ProxiedPlayer player = serverConnectedEvent.getPlayer();
|
||||||
Server server = serverConnectedEvent.getServer();
|
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);
|
ProxyServer.getInstance().getScheduler().runAsync(plugin, loginTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,13 +68,13 @@ public class PluginMessageListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
core.getPendingConfirms().remove(forPlayer.getUniqueId());
|
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);
|
ProxyServer.getInstance().getScheduler().runAsync(plugin, task);
|
||||||
} else if ("OFF".equals(subchannel)) {
|
} else if ("OFF".equals(subchannel)) {
|
||||||
String playerName = dataInput.readUTF();
|
String playerName = dataInput.readUTF();
|
||||||
boolean isPlayerSender = dataInput.readBoolean();
|
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);
|
ProxyServer.getInstance().getScheduler().runAsync(plugin, task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 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
|
# This make it easy to combine BungeeCord and Bukkit support in one plugin
|
||||||
name: ${project.parent.name}
|
name: ${project.parent.name}
|
||||||
@ -13,4 +13,4 @@ softDepends:
|
|||||||
- BungeeAuth
|
- BungeeAuth
|
||||||
|
|
||||||
description: |
|
description: |
|
||||||
${project.description}
|
${project.description}
|
||||||
|
@ -15,6 +15,8 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
public class AuthStorage {
|
public class AuthStorage {
|
||||||
|
|
||||||
private static final String PREMIUM_TABLE = "premium";
|
private static final String PREMIUM_TABLE = "premium";
|
||||||
@ -63,7 +65,7 @@ public class AuthStorage {
|
|||||||
this.dataSource = new HikariDataSource(databaseConfig);
|
this.dataSource = new HikariDataSource(databaseConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HikariDataSource getDataSource() {
|
public DataSource getDataSource() {
|
||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +85,7 @@ public class AuthStorage {
|
|||||||
+ "LastLogin TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "
|
+ "LastLogin TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "
|
||||||
//the premium shouldn't steal the cracked account by changing the name
|
//the premium shouldn't steal the cracked account by changing the name
|
||||||
+ "UNIQUE (Name) "
|
+ "UNIQUE (Name) "
|
||||||
+ ")";
|
+ ')';
|
||||||
|
|
||||||
if (dataSource.getJdbcUrl().contains("sqlite")) {
|
if (dataSource.getJdbcUrl().contains("sqlite")) {
|
||||||
createDataStmt = createDataStmt.replace("AUTO_INCREMENT", "AUTOINCREMENT");
|
createDataStmt = createDataStmt.replace("AUTO_INCREMENT", "AUTOINCREMENT");
|
||||||
@ -142,11 +144,9 @@ public class AuthStorage {
|
|||||||
boolean premium = resultSet.getBoolean(4);
|
boolean premium = resultSet.getBoolean(4);
|
||||||
String lastIp = resultSet.getString(5);
|
String lastIp = resultSet.getString(5);
|
||||||
long lastLogin = resultSet.getTimestamp(6).getTime();
|
long lastLogin = resultSet.getTimestamp(6).getTime();
|
||||||
PlayerProfile playerProfile = new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
|
return new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
|
||||||
return playerProfile;
|
|
||||||
} else {
|
} else {
|
||||||
PlayerProfile crackedProfile = new PlayerProfile(null, name, false, "");
|
return new PlayerProfile(null, name, false, "");
|
||||||
return crackedProfile;
|
|
||||||
}
|
}
|
||||||
} catch (SQLException sqlEx) {
|
} catch (SQLException sqlEx) {
|
||||||
core.getPlugin().getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
|
core.getPlugin().getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
|
||||||
@ -176,8 +176,7 @@ public class AuthStorage {
|
|||||||
boolean premium = resultSet.getBoolean(4);
|
boolean premium = resultSet.getBoolean(4);
|
||||||
String lastIp = resultSet.getString(5);
|
String lastIp = resultSet.getString(5);
|
||||||
long lastLogin = resultSet.getTimestamp(6).getTime();
|
long lastLogin = resultSet.getTimestamp(6).getTime();
|
||||||
PlayerProfile playerProfile = new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
|
return new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
|
||||||
return playerProfile;
|
|
||||||
}
|
}
|
||||||
} catch (SQLException sqlEx) {
|
} catch (SQLException sqlEx) {
|
||||||
core.getPlugin().getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
|
core.getPlugin().getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
|
||||||
|
@ -54,7 +54,7 @@ public class CompatibleCacheBuilder<K, V> {
|
|||||||
* @param concurrencyLevel New concurrency level
|
* @param concurrencyLevel New concurrency level
|
||||||
* @return This for chaining
|
* @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
|
* @throws IllegalStateException if a concurrency level was already set
|
||||||
*/
|
*/
|
||||||
public CompatibleCacheBuilder<K, V> concurrencyLevel(int concurrencyLevel) {
|
public CompatibleCacheBuilder<K, V> concurrencyLevel(int concurrencyLevel) {
|
||||||
@ -76,7 +76,7 @@ public class CompatibleCacheBuilder<K, V> {
|
|||||||
* <p>
|
* <p>
|
||||||
* Expired entries may be counted by {@link com.google.common.cache.Cache#size Cache.size()}, but will never be
|
* 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
|
* 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 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
|
* @param unit the unit that {@code duration} is expressed in
|
||||||
@ -102,7 +102,7 @@ public class CompatibleCacheBuilder<K, V> {
|
|||||||
* <p>
|
* <p>
|
||||||
* Expired entries may be counted by {@link com.google.common.cache.Cache#size Cache.size()}, but will never be
|
* 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
|
* 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 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
|
* @param unit the unit that {@code duration} is expressed in
|
||||||
@ -284,7 +284,7 @@ public class CompatibleCacheBuilder<K, V> {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <K1 extends K, V1 extends V> ConcurrentMap<K1, V1> build(CacheLoader<? super K1, V1> loader) {
|
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) {
|
if (BUILD_METHOD == null) {
|
||||||
try {
|
try {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.github.games647.fastlogin.core.hooks;
|
package com.github.games647.fastlogin.core.hooks;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
public interface PasswordGenerator<P> {
|
public interface PasswordGenerator<P> {
|
||||||
|
|
||||||
String getRandomPassword(P player);
|
String getRandomPassword(P player);
|
||||||
|
@ -21,6 +21,7 @@ import java.nio.file.Path;
|
|||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
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)
|
return UUID.fromString(withoutDashes.substring(0, 8)
|
||||||
+ "-" + withoutDashes.substring(8, 12)
|
+ '-' + withoutDashes.substring(8, 12)
|
||||||
+ "-" + withoutDashes.substring(12, 16)
|
+ '-' + withoutDashes.substring(12, 16)
|
||||||
+ "-" + withoutDashes.substring(16, 20)
|
+ '-' + withoutDashes.substring(16, 20)
|
||||||
+ "-" + withoutDashes.substring(20, 32));
|
+ '-' + withoutDashes.substring(20, 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final Map<String, String> localeMessages = new ConcurrentHashMap<>();
|
protected final Map<String, String> localeMessages = new ConcurrentHashMap<>();
|
||||||
@ -198,7 +199,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
|||||||
} else {
|
} else {
|
||||||
Class.forName("com.mysql.jdbc.Driver");
|
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);
|
Connection con = DriverManager.getConnection(jdbcUrl, username, pass);
|
||||||
importer.importData(con, storage.getDataSource(), storage);
|
importer.importData(con, storage.getDataSource(), storage);
|
||||||
return true;
|
return true;
|
||||||
@ -228,7 +229,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
|||||||
return pendingLogins;
|
return pendingLogins;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<UUID> getPendingConfirms() {
|
public Collection<UUID> getPendingConfirms() {
|
||||||
return pendingConfirms;
|
return pendingConfirms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import java.net.HttpURLConnection;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.List;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
@ -43,7 +43,7 @@ public abstract class MojangApiConnector {
|
|||||||
|
|
||||||
protected final Logger logger;
|
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;
|
this.logger = logger;
|
||||||
|
|
||||||
if (rateLimit > 600) {
|
if (rateLimit > 600) {
|
||||||
@ -95,7 +95,7 @@ public abstract class MojangApiConnector {
|
|||||||
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||||
String line = reader.readLine();
|
String line = reader.readLine();
|
||||||
if (!line.equals("null")) {
|
if (!"null".equals(line)) {
|
||||||
return FastLoginCore.parseId(getUUIDFromJson(line));
|
return FastLoginCore.parseId(getUUIDFromJson(line));
|
||||||
}
|
}
|
||||||
} else if (connection.getResponseCode() == RATE_LIMIT_CODE) {
|
} else if (connection.getResponseCode() == RATE_LIMIT_CODE) {
|
||||||
|
24
pom.xml
24
pom.xml
@ -29,17 +29,6 @@
|
|||||||
<module>universal</module>
|
<module>universal</module>
|
||||||
</modules>
|
</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>
|
<build>
|
||||||
<defaultGoal>install</defaultGoal>
|
<defaultGoal>install</defaultGoal>
|
||||||
<!--Just use the project name to replace an old version of the plugin if the user does only copy-paste-->
|
<!--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>
|
<configuration>
|
||||||
<source>1.8</source>
|
<source>1.8</source>
|
||||||
<target>1.8</target>
|
<target>1.8</target>
|
||||||
<showWarnings>true</showWarnings>
|
|
||||||
<showDeprecation>true</showDeprecation>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>pl.project13.maven</groupId>
|
<groupId>pl.project13.maven</groupId>
|
||||||
<artifactId>git-commit-id-plugin</artifactId>
|
<artifactId>git-commit-id-plugin</artifactId>
|
||||||
<version>2.2.1</version>
|
<version>2.2.2</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<failOnNoGitDirectory>false</failOnNoGitDirectory>
|
<failOnNoGitDirectory>false</failOnNoGitDirectory>
|
||||||
</configuration>
|
</configuration>
|
||||||
@ -82,15 +69,6 @@
|
|||||||
<!--Replace variables-->
|
<!--Replace variables-->
|
||||||
<filtering>true</filtering>
|
<filtering>true</filtering>
|
||||||
</resource>
|
</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>
|
</resources>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.4.3</version>
|
<version>3.0.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||||
@ -43,15 +43,6 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</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>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user