mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-07-29 18:27:36 +02:00
Add second attemp login -> cracked (Fixes #51)
This commit is contained in:
@ -1,3 +1,7 @@
|
||||
######1.9
|
||||
|
||||
* Added second attempt login -> cracked login
|
||||
|
||||
######1.8
|
||||
|
||||
* Added autoIn importer
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.github.games647</groupId>
|
||||
<artifactId>fastlogin</artifactId>
|
||||
<version>1.8</version>
|
||||
<version>1.9</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -2,11 +2,14 @@ package com.github.games647.fastlogin.bukkit;
|
||||
|
||||
import com.github.games647.fastlogin.core.FastLoginCore;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
@ -14,9 +17,30 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
public class BukkitCore extends FastLoginCore {
|
||||
|
||||
public static <K, V> ConcurrentMap<K, V> buildCache(int minutes, int maxSize) {
|
||||
CompatibleCacheBuilder<Object, Object> builder = CompatibleCacheBuilder.newBuilder();
|
||||
|
||||
if (minutes > 0) {
|
||||
builder.expireAfterWrite(minutes, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
if (maxSize > 0) {
|
||||
builder.maximumSize(maxSize);
|
||||
}
|
||||
|
||||
return builder.build(new CacheLoader<K, V>() {
|
||||
@Override
|
||||
public V load(K key) throws Exception {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private final FastLoginBukkit plugin;
|
||||
|
||||
public BukkitCore(FastLoginBukkit plugin) {
|
||||
super(BukkitCore.<String, Object>buildCache(5, 0));
|
||||
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@ import com.github.games647.fastlogin.bukkit.listener.protocollib.StartPacketList
|
||||
import com.github.games647.fastlogin.bukkit.listener.protocolsupport.ProtocolSupportListener;
|
||||
import com.github.games647.fastlogin.bukkit.tasks.DelayedAuthHook;
|
||||
import com.github.games647.fastlogin.core.FastLoginCore;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.security.KeyPair;
|
||||
@ -23,7 +22,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
@ -47,7 +45,7 @@ public class FastLoginBukkit extends JavaPlugin {
|
||||
|
||||
//this map is thread-safe for async access (Packet Listener)
|
||||
//SafeCacheBuilder is used in order to be version independent
|
||||
private final ConcurrentMap<String, BukkitLoginSession> session = buildCache(1, -1);
|
||||
private final ConcurrentMap<String, BukkitLoginSession> session = BukkitCore.buildCache(1, -1);
|
||||
//1 minutes should be enough as a timeout for bad internet connection (Server, Client and Mojang)
|
||||
|
||||
private BukkitAuthPlugin authPlugin;
|
||||
@ -60,7 +58,8 @@ public class FastLoginBukkit extends JavaPlugin {
|
||||
|
||||
List<String> ipAddresses = getConfig().getStringList("ip-addresses");
|
||||
int requestLimit = getConfig().getInt("mojang-request-limit");
|
||||
MojangApiBukkit mojangApi = new MojangApiBukkit(buildCache(10, -1), getLogger(), ipAddresses, requestLimit);
|
||||
ConcurrentMap<Object, Object> requestCache = BukkitCore.buildCache(10, -1);
|
||||
MojangApiBukkit mojangApi = new MojangApiBukkit(requestCache, getLogger(), ipAddresses, requestLimit);
|
||||
core.setMojangApiConnector(mojangApi);
|
||||
|
||||
try {
|
||||
@ -220,23 +219,4 @@ public class FastLoginBukkit extends JavaPlugin {
|
||||
this.serverStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
private <K, V> ConcurrentMap<K, V> buildCache(int minutes, int maxSize) {
|
||||
CompatibleCacheBuilder<Object, Object> builder = CompatibleCacheBuilder.newBuilder();
|
||||
|
||||
if (minutes > 0) {
|
||||
builder.expireAfterWrite(minutes, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
if (maxSize > 0) {
|
||||
builder.maximumSize(maxSize);
|
||||
}
|
||||
|
||||
return builder.build(new CacheLoader<K, V>() {
|
||||
@Override
|
||||
public V load(K key) throws Exception {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,18 @@ public class NameCheckTask implements Runnable {
|
||||
|
||||
if (profile.getUserId() == -1) {
|
||||
UUID premiumUUID = null;
|
||||
|
||||
|
||||
String ip = player.getAddress().getAddress().getHostAddress();
|
||||
if (plugin.getCore().getPendingLogins().containsKey(ip + username)
|
||||
&& plugin.getConfig().getBoolean("secondAttemptCracked")) {
|
||||
plugin.getLogger().log(Level.INFO, "Second attempt login -> cracked {0}", username);
|
||||
|
||||
//first login request failed so make a cracked session
|
||||
BukkitLoginSession loginSession = new BukkitLoginSession(username, profile);
|
||||
plugin.getSessions().put(player.getAddress().toString(), loginSession);
|
||||
return;
|
||||
}
|
||||
|
||||
//user not exists in the db
|
||||
try {
|
||||
boolean isRegistered = plugin.getAuthPlugin().isRegistered(username);
|
||||
@ -105,6 +116,9 @@ public class NameCheckTask implements Runnable {
|
||||
|
||||
boolean success = sentEncryptionRequest(player, serverId, verify);
|
||||
if (success) {
|
||||
String ip = player.getAddress().getAddress().getHostAddress();
|
||||
plugin.getCore().getPendingLogins().put(ip + username, new Object());
|
||||
|
||||
BukkitLoginSession playerSession = new BukkitLoginSession(username, serverId, verify, registered, profile);
|
||||
plugin.getSessions().put(player.getAddress().toString(), playerSession);
|
||||
//cancel only if the player has a paid account otherwise login as normal offline player
|
||||
|
@ -50,6 +50,9 @@ public class VerifyResponseTask implements Runnable {
|
||||
disconnect(plugin.getCore().getMessage("invalid-requst"), true
|
||||
, "Player {0} tried to send encryption response at invalid state", fromPlayer.getAddress());
|
||||
} else {
|
||||
String ip = fromPlayer.getAddress().getAddress().getHostAddress();
|
||||
plugin.getCore().getPendingLogins().remove(ip + session.getUsername());
|
||||
|
||||
verifyResponse(session);
|
||||
}
|
||||
} finally {
|
||||
|
@ -31,9 +31,10 @@ public class ProtocolSupportListener implements Listener {
|
||||
}
|
||||
|
||||
String username = loginStartEvent.getName();
|
||||
InetSocketAddress address = loginStartEvent.getAddress();
|
||||
|
||||
//remove old data every time on a new login in order to keep the session only for one person
|
||||
plugin.getSessions().remove(loginStartEvent.getAddress().toString());
|
||||
plugin.getSessions().remove(address.toString());
|
||||
|
||||
BukkitAuthPlugin authPlugin = plugin.getAuthPlugin();
|
||||
if (authPlugin == null) {
|
||||
@ -43,6 +44,18 @@ public class ProtocolSupportListener implements Listener {
|
||||
PlayerProfile profile = plugin.getCore().getStorage().loadProfile(username);
|
||||
if (profile != null) {
|
||||
if (profile.getUserId() == -1) {
|
||||
|
||||
String ip = address.getAddress().getHostAddress();
|
||||
if (plugin.getCore().getPendingLogins().containsKey(ip + username)
|
||||
&& plugin.getConfig().getBoolean("secondAttemptCracked")) {
|
||||
plugin.getLogger().log(Level.INFO, "Second attempt login -> cracked {0}", username);
|
||||
|
||||
//first login request failed so make a cracked session
|
||||
BukkitLoginSession loginSession = new BukkitLoginSession(username, profile);
|
||||
plugin.getSessions().put(address.toString(), loginSession);
|
||||
return;
|
||||
}
|
||||
|
||||
UUID premiumUUID = null;
|
||||
|
||||
//user not exists in the db
|
||||
@ -70,7 +83,7 @@ public class ProtocolSupportListener implements Listener {
|
||||
|
||||
//no premium check passed so we save it as a cracked player
|
||||
BukkitLoginSession loginSession = new BukkitLoginSession(username, profile);
|
||||
plugin.getSessions().put(loginStartEvent.getAddress().toString(), loginSession);
|
||||
plugin.getSessions().put(address.toString(), loginSession);
|
||||
} catch (Exception ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Failed to query isRegistered", ex);
|
||||
}
|
||||
@ -78,7 +91,7 @@ public class ProtocolSupportListener implements Listener {
|
||||
startPremiumSession(username, loginStartEvent, true, profile);
|
||||
} else {
|
||||
BukkitLoginSession loginSession = new BukkitLoginSession(username, profile);
|
||||
plugin.getSessions().put(loginStartEvent.getAddress().toString(), loginSession);
|
||||
plugin.getSessions().put(address.toString(), loginSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,17 +103,23 @@ public class ProtocolSupportListener implements Listener {
|
||||
InetSocketAddress address = propertiesResolveEvent.getAddress();
|
||||
BukkitLoginSession session = plugin.getSessions().get(address.toString());
|
||||
if (session != null) {
|
||||
String ip = address.getAddress().getHostAddress();
|
||||
plugin.getCore().getPendingLogins().remove(ip + session.getUsername());
|
||||
|
||||
session.setVerified(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startPremiumSession(String playerName, PlayerLoginStartEvent loginStartEvent, boolean registered
|
||||
private void startPremiumSession(String username, PlayerLoginStartEvent loginStartEvent, boolean registered
|
||||
, PlayerProfile playerProfile) {
|
||||
loginStartEvent.setOnlineMode(true);
|
||||
InetSocketAddress address = loginStartEvent.getAddress();
|
||||
|
||||
BukkitLoginSession playerSession = new BukkitLoginSession(playerName, null, null, registered, playerProfile);
|
||||
String ip = address.getAddress().getHostAddress();
|
||||
plugin.getCore().getPendingLogins().put(ip + username, new Object());
|
||||
|
||||
BukkitLoginSession playerSession = new BukkitLoginSession(username, null, null, registered, playerProfile);
|
||||
plugin.getSessions().put(address.toString(), playerSession);
|
||||
if (plugin.getConfig().getBoolean("premiumUuid")) {
|
||||
loginStartEvent.setUseOnlineModeUUID(true);
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.github.games647</groupId>
|
||||
<artifactId>fastlogin</artifactId>
|
||||
<version>1.8</version>
|
||||
<version>1.9</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.github.games647.fastlogin.bungee;
|
||||
|
||||
import com.github.games647.fastlogin.core.FastLoginCore;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
|
||||
import java.io.File;
|
||||
@ -8,10 +9,11 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.scheduler.GroupedThreadFactory;
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
import net.md_5.bungee.config.ConfigurationProvider;
|
||||
@ -22,6 +24,8 @@ public class BungeeCore extends FastLoginCore {
|
||||
private final FastLoginBungee plugin;
|
||||
|
||||
public BungeeCore(FastLoginBungee plugin) {
|
||||
super(CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES).<String, Object>build().asMap());
|
||||
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,9 @@ public class PlayerConnectionListener implements Listener {
|
||||
PendingConnection connection = loginEvent.getConnection();
|
||||
String username = connection.getName();
|
||||
if (connection.isOnlineMode()) {
|
||||
String ip = connection.getAddress().getAddress().getHostAddress();
|
||||
plugin.getCore().getPendingLogins().remove(ip + username);
|
||||
|
||||
LoginSession session = plugin.getSession().get(connection);
|
||||
PlayerProfile playerProfile = session.getProfile();
|
||||
playerProfile.setUuid(connection.getUniqueId());
|
||||
|
@ -27,13 +27,23 @@ public class AsyncPremiumCheck implements Runnable {
|
||||
plugin.getSession().remove(connection);
|
||||
|
||||
String username = connection.getName();
|
||||
try {
|
||||
PlayerProfile profile = plugin.getCore().getStorage().loadProfile(username);
|
||||
if (profile == null) {
|
||||
return;
|
||||
}
|
||||
PlayerProfile profile = plugin.getCore().getStorage().loadProfile(username);
|
||||
if (profile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (profile.getUserId() == -1) {
|
||||
String ip = connection.getAddress().getAddress().getHostAddress();
|
||||
if (plugin.getCore().getPendingLogins().containsKey(ip + username)
|
||||
&& plugin.getConfig().getBoolean("secondAttemptCracked")) {
|
||||
plugin.getLogger().log(Level.INFO, "Second attempt login -> cracked {0}", username);
|
||||
|
||||
//first login request failed so make a cracked session
|
||||
plugin.getSession().put(connection, new BungeeLoginSession(username, false, profile));
|
||||
return;
|
||||
}
|
||||
|
||||
UUID premiumUUID = null;
|
||||
if (plugin.getConfig().getBoolean("nameChangeCheck") || plugin.getConfig().getBoolean("autoRegister")) {
|
||||
premiumUUID = plugin.getCore().getMojangApiConnector().getPremiumUUID(username);
|
||||
@ -89,5 +99,8 @@ public class AsyncPremiumCheck implements Runnable {
|
||||
private void requestPremiumLogin(PendingConnection con, PlayerProfile profile, String username, boolean register) {
|
||||
con.setOnlineMode(true);
|
||||
plugin.getSession().put(con, new BungeeLoginSession(username, register, profile));
|
||||
|
||||
String ip = con.getAddress().getAddress().getHostAddress();
|
||||
plugin.getCore().getPendingLogins().put(ip + username, new Object());
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.github.games647</groupId>
|
||||
<artifactId>fastlogin</artifactId>
|
||||
<version>1.8</version>
|
||||
<version>1.9</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -11,6 +11,7 @@ import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -30,9 +31,16 @@ public abstract class FastLoginCore {
|
||||
}
|
||||
|
||||
protected final Map<String, String> localeMessages = new ConcurrentHashMap<>();
|
||||
|
||||
private final ConcurrentMap<String, Object> pendingLogins;
|
||||
|
||||
private MojangApiConnector mojangApiConnector;
|
||||
private AuthStorage storage;
|
||||
|
||||
public FastLoginCore(ConcurrentMap<String, Object> pendingLogins) {
|
||||
this.pendingLogins = pendingLogins;
|
||||
}
|
||||
|
||||
public void setMojangApiConnector(MojangApiConnector mojangApiConnector) {
|
||||
this.mojangApiConnector = mojangApiConnector;
|
||||
}
|
||||
@ -110,6 +118,10 @@ public abstract class FastLoginCore {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ConcurrentMap<String, Object> getPendingLogins() {
|
||||
return pendingLogins;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (storage != null) {
|
||||
storage.close();
|
||||
|
@ -21,6 +21,14 @@
|
||||
# For more information: https://github.com/games647/FastLogin#why-do-players-have-to-invoke-a-command
|
||||
autoRegister: false
|
||||
|
||||
# This is extra configuration option to the feature above. If we request a premium authentication from a player who
|
||||
# isn't actual premium but used a premium username, the player will disconnect with the reason "invalid session" or
|
||||
# "bad login".
|
||||
#
|
||||
# If you activate this, we are remembering this player and do not force another premium authentication if the player
|
||||
# tries to join again, so the player could join as cracked player.
|
||||
secondAttemptCracked: false
|
||||
|
||||
# If this plugin detected that a player has a premium, it can also set the associated
|
||||
# uuid from that account. So if the players changes their usernames, they will still have
|
||||
# the same playerdata (inventory, permissions, ...)
|
||||
|
2
pom.xml
2
pom.xml
@ -8,7 +8,7 @@
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>FastLogin</name>
|
||||
<version>1.8</version>
|
||||
<version>1.9</version>
|
||||
<inceptionYear>2015</inceptionYear>
|
||||
<url>https://www.spigotmc.org/resources/fastlogin.14153/</url>
|
||||
<description>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.github.games647</groupId>
|
||||
<artifactId>fastlogin</artifactId>
|
||||
<version>1.8</version>
|
||||
<version>1.9</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
Reference in New Issue
Block a user