package io.github.lucaseasedup.logit.command;
import static io.github.lucaseasedup.logit.message.MessageHelper.sendMsg;
import static io.github.lucaseasedup.logit.message.MessageHelper.t;
import io.github.lucaseasedup.logit.LogItCoreObject;
import io.github.lucaseasedup.logit.account.Account;
import io.github.lucaseasedup.logit.common.PlayerCollections;
import io.github.lucaseasedup.logit.config.TimeUnit;
import io.github.lucaseasedup.logit.hooks.BukkitSmerfHook;
import io.github.lucaseasedup.logit.locale.Locale;
import io.github.lucaseasedup.logit.util.PlayerUtils;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
public final class LoginCommand extends LogItCoreObject
implements CommandExecutor
{
@Override
public boolean onCommand(
CommandSender sender, Command cmd, String label, String[] args
)
{
final Player player;
if (sender instanceof Player)
{
player = (Player) sender;
}
else
{
player = null;
}
boolean disablePasswords = getConfig("secret.yml")
.getBoolean("passwords.disable");
if (args.length > 0 && args[0].equals("-x") && args.length <= 2)
{
if (player != null && (
(getCore().isPlayerForcedToLogIn(player)
&& !getSessionManager().isSessionAlive(player))
|| !player.hasPermission("logit.login.others")
))
{
sendMsg(sender, t("noPerms"));
return true;
}
if (args.length < 2)
{
sendMsg(sender, t("paramMissing")
.replace("{0}", "player"));
return true;
}
if (!PlayerUtils.isPlayerOnline(args[1]))
{
sendMsg(sender, t("playerNotOnline")
.replace("{0}", args[1]));
return true;
}
Player paramPlayer = Bukkit.getPlayerExact(args[1]);
if (getSessionManager().isSessionAlive(paramPlayer))
{
sendMsg(sender, t("alreadyLoggedIn.others")
.replace("{0}", paramPlayer.getName()));
return true;
}
if (getSessionManager().getSession(paramPlayer) == null)
{
getSessionManager().createSession(paramPlayer);
}
if (!getSessionManager().startSession(paramPlayer).isCancelled())
{
sendMsg(paramPlayer, t("startSession.success.self"));
sendMsg(sender, t("startSession.success.others")
.replace("{0}", paramPlayer.getName()));
if (getConfig("config.yml").getBoolean("stats.enabled"))
{
getConfig("stats.yml").set("logins",
getConfig("stats.yml").getInt("logins") + 1);
}
}
}
else if ((args.length == 0 && disablePasswords)
|| (args.length <= 1 && !disablePasswords))
{
if (player == null)
{
sendMsg(sender, t("onlyForPlayers"));
return true;
}
if (!player.hasPermission("logit.login.self"))
{
sendMsg(player, t("noPerms"));
return true;
}
if (args.length < 1 && !disablePasswords)
{
sendMsg(player, t("paramMissing")
.replace("{0}", "password"));
return true;
}
if (getSessionManager().isSessionAlive(player))
{
sendMsg(player, t("alreadyLoggedIn.self"));
return true;
}
if (loginBlockade.containsKey(player))
{
long blockadeExpirationTimeMillis = loginBlockade.get(player);
Locale locale = getLocaleManager().getActiveLocale();
if (blockadeExpirationTimeMillis - 1000L > System.currentTimeMillis())
{
long blockageTimeSecs = TimeUnit.MILLISECONDS.convertTo(
blockadeExpirationTimeMillis - System.currentTimeMillis(),
TimeUnit.SECONDS
);
sendMsg(player, t("tooManyLoginFails.blockLoggingIn")
.replace("{0}", locale.stringifySeconds(blockageTimeSecs)));
return true;
}
loginBlockade.remove(player);
}
Account account = getAccountManager().selectAccount(
player.getName(),
Arrays.asList(
keys().username(),
keys().salt(),
keys().password(),
keys().hashing_algorithm(),
keys().ip(),
keys().login_history(),
keys().persistence()
)
);
if (account == null)
{
sendMsg(player, t("notRegistered.self"));
return true;
}
String playerIp = PlayerUtils.getPlayerIp(player);
long currentTimeSecs = System.currentTimeMillis() / 1000L;
if (!disablePasswords
&& !getGlobalPasswordManager().checkPassword(args[0]))
{
if (!account.checkPassword(args[0]))
{
sendMsg(player, t("incorrectPassword"));
int failsToBlockLoggingIn = getConfig("config.yml")
.getInt("bruteForce.blockLogin.attempts");
int failsToKick = getConfig("config.yml")
.getInt("bruteForce.kick.attempts");
int failsToBan = getConfig("config.yml")
.getInt("bruteForce.ban.attempts");
Integer currentFailedLogins = failedLogins.get(player);
failedLogins.put(player,
currentFailedLogins != null ? currentFailedLogins + 1 : 1);
if (playerIp != null && failsToBan > 0
&& failedLogins.get(player) >= failsToBan)
{
Bukkit.banIP(playerIp);
player.kickPlayer(t("tooManyLoginFails.ban"));
failedLogins.remove(player);
}
else if (failsToKick > 0
&& failedLogins.get(player) >= failsToKick)
{
player.kickPlayer(t("tooManyLoginFails.kick"));
failedLogins.remove(player);
}
else if (failsToBlockLoggingIn > 0
&& failedLogins.get(player) >= failsToBlockLoggingIn)
{
long loginBlockadeTimeMillis = getConfig("config.yml")
.getTime("bruteForce.blockLogin.forTime",
TimeUnit.MILLISECONDS);
long loginBlockadeTimeSecs = TimeUnit.MILLISECONDS.convertTo(
loginBlockadeTimeMillis,
TimeUnit.SECONDS
);
loginBlockade.put(player,
System.currentTimeMillis() + loginBlockadeTimeMillis);
Locale locale = getLocaleManager().getActiveLocale();
String localeBlockadeTime =
locale.stringifySeconds(loginBlockadeTimeSecs);
sendMsg(player, t("tooManyLoginFails.blockLoggingIn")
.replace("{0}", localeBlockadeTime));
failedLogins.remove(player);
}
if (getConfig("config.yml").getBoolean("loginHistory.enabled"))
{
account.recordLogin(currentTimeSecs, playerIp, Account.LOGIN_FAIL);
}
boolean isPremium = BukkitSmerfHook.isPremium(player);
boolean premiumTakeoverEnabled = getConfig("config.yml")
.getBoolean("premiumTakeover.enabled");
String promptOn = getConfig("config.yml")
.getString("premiumTakeover.promptOn");
if (isPremium && premiumTakeoverEnabled
&& promptOn.equals("failed-login"))
{
new BukkitRunnable()
{
@Override
public void run()
{
if (!getSessionManager().isSessionAlive(player))
{
sendMsg(player, t("takeover.prompt"));
}
}
}.runTaskLater(getPlugin(), 20L);
}
return true;
}
}
failedLogins.remove(player);
if (getSessionManager().getSession(player) == null)
{
getSessionManager().createSession(player);
}
if (!getSessionManager().startSession(player).isCancelled())
{
sendMsg(sender, t("startSession.success.self"));
if (getConfig("config.yml").getBoolean("stats.enabled"))
{
getConfig("stats.yml").set("logins",
getConfig("stats.yml").getInt("logins") + 1);
}
if (getConfig("config.yml").getBoolean("loginSessions.enabled"))
{
sendMsg(sender, t("rememberLogin.prompt"));
}
if (getConfig("config.yml").getBoolean("loginHistory.enabled"))
{
account.recordLogin(currentTimeSecs, playerIp, Account.LOGIN_SUCCESS);
}
if (playerIp != null && StringUtils.isBlank(account.getIp()))
{
account.setIp(playerIp);
}
}
}
else
{
sendMsg(sender, t("incorrectParamCombination"));
}
return true;
}
private final Map<Player, Integer> failedLogins =
PlayerCollections.monitoredMap(new HashMap<Player, Integer>());
private final Map<Player, Long> loginBlockade =
PlayerCollections.monitoredMap(new HashMap<Player, Long>());
}