291 lines
11 KiB
Java
291 lines
11 KiB
Java
package me.totalfreedom.totalfreedommod;
|
|
|
|
import com.google.common.base.Strings;
|
|
import io.papermc.lib.PaperLib;
|
|
import me.totalfreedom.totalfreedommod.admin.Admin;
|
|
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
import me.totalfreedom.totalfreedommod.player.FPlayer;
|
|
import me.totalfreedom.totalfreedommod.player.PlayerData;
|
|
import me.totalfreedom.totalfreedommod.util.FConverter;
|
|
import me.totalfreedom.totalfreedommod.util.FSync;
|
|
import me.totalfreedom.totalfreedommod.util.FUtil;
|
|
import net.kyori.adventure.text.Component;
|
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
|
import org.bukkit.event.player.PlayerJoinEvent;
|
|
import org.bukkit.event.player.PlayerLoginEvent;
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
import java.util.regex.Pattern;
|
|
|
|
public class LoginProcess extends FreedomService
|
|
{
|
|
public static final int DEFAULT_PORT = 25565;
|
|
public static final int MIN_USERNAME_LENGTH = 2;
|
|
public static final int MAX_USERNAME_LENGTH = 20;
|
|
public static final Pattern USERNAME_REGEX = Pattern.compile("^[\\w\\d_]{3,20}$");
|
|
private static boolean lockdownEnabled = false;
|
|
public List<String> TELEPORT_ON_JOIN = new ArrayList<>();
|
|
public List<String> CLEAR_ON_JOIN = new ArrayList<>();
|
|
|
|
public static boolean isLockdownEnabled()
|
|
{
|
|
return lockdownEnabled;
|
|
}
|
|
|
|
public static void setLockdownEnabled(boolean lockdownEnabled)
|
|
{
|
|
LoginProcess.lockdownEnabled = lockdownEnabled;
|
|
}
|
|
|
|
@Override
|
|
public void onStart()
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public void onStop()
|
|
{
|
|
}
|
|
|
|
/*
|
|
* Banning and Permban checks are their respective services
|
|
*/
|
|
@EventHandler(priority = EventPriority.NORMAL)
|
|
public void onPlayerPreLogin(AsyncPlayerPreLoginEvent event)
|
|
{
|
|
final Admin entry = plugin.al.getEntryByUuid(event.getUniqueId());
|
|
final boolean isAdmin = entry != null && entry.isActive();
|
|
|
|
// Check if the player is already online
|
|
for (Player onlinePlayer : server.getOnlinePlayers())
|
|
{
|
|
if (!onlinePlayer.getUniqueId().equals(event.getUniqueId()))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (isAdmin)
|
|
{
|
|
event.allow();
|
|
FSync.playerKick(onlinePlayer, "An admin just logged in with the username you are using.");
|
|
return;
|
|
}
|
|
|
|
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "Your username is already logged into this server.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGH)
|
|
public void onPlayerLogin(PlayerLoginEvent event)
|
|
{
|
|
final Player player = event.getPlayer();
|
|
final String username = player.getName();
|
|
final UUID uuid = player.getUniqueId();
|
|
|
|
// Check username length
|
|
if (username.length() < MIN_USERNAME_LENGTH || username.length() > MAX_USERNAME_LENGTH)
|
|
{
|
|
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Your username is an invalid length (must be between 3 and 20 characters long).");
|
|
return;
|
|
}
|
|
|
|
// Check username characters
|
|
if (!USERNAME_REGEX.matcher(username).find())
|
|
{
|
|
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Your username contains invalid characters.");
|
|
return;
|
|
}
|
|
|
|
// Check force-IP match
|
|
if (ConfigEntry.FORCE_IP_ENABLED.getBoolean())
|
|
{
|
|
final String hostname = event.getHostname().replace("\u0000FML\u0000", ""); // Forge fix - https://github.com/TotalFreedom/TotalFreedomMod/issues/493
|
|
final String connectAddress = ConfigEntry.SERVER_ADDRESS.getString();
|
|
final int connectPort = server.getPort();
|
|
|
|
if (!hostname.equalsIgnoreCase(connectAddress + ":" + connectPort) && !hostname.equalsIgnoreCase(connectAddress + ".:" + connectPort))
|
|
{
|
|
final int forceIpPort = ConfigEntry.FORCE_IP_PORT.getInteger();
|
|
event.disallow(PlayerLoginEvent.Result.KICK_OTHER,
|
|
ConfigEntry.FORCE_IP_KICKMSG.getString()
|
|
.replace("%address%", ConfigEntry.SERVER_ADDRESS.getString() + (forceIpPort == DEFAULT_PORT ? "" : ":" + forceIpPort)));
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Validation below this point
|
|
final Admin entry = plugin.al.getEntryByUuid(uuid);
|
|
if (entry != null && entry.isActive()) // Check if player is admin
|
|
{
|
|
// Force-allow log in
|
|
event.allow();
|
|
|
|
int count = server.getOnlinePlayers().size();
|
|
if (count >= server.getMaxPlayers())
|
|
{
|
|
for (Player onlinePlayer : server.getOnlinePlayers())
|
|
{
|
|
if (!plugin.al.isAdmin(onlinePlayer))
|
|
{
|
|
onlinePlayer.kickPlayer("You have been kicked to free up room for an admin.");
|
|
count--;
|
|
}
|
|
|
|
if (count < server.getMaxPlayers())
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count >= server.getMaxPlayers())
|
|
{
|
|
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "The server is full and a player could not be kicked, sorry!");
|
|
return;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Player is not an admin
|
|
// Server full check
|
|
if (server.getOnlinePlayers().size() >= server.getMaxPlayers())
|
|
{
|
|
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Sorry, but this server is full.");
|
|
return;
|
|
}
|
|
|
|
// Admin-only mode
|
|
if (ConfigEntry.ADMIN_ONLY_MODE.getBoolean())
|
|
{
|
|
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Server is temporarily open to admins only.");
|
|
return;
|
|
}
|
|
|
|
// Lockdown mode
|
|
if (lockdownEnabled)
|
|
{
|
|
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Server is currently in lockdown mode.");
|
|
return;
|
|
}
|
|
|
|
// Whitelist
|
|
if (server.hasWhitelist() && !player.isWhitelisted())
|
|
{
|
|
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "You are not whitelisted on this server.");
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR)
|
|
public void onPlayerJoin(PlayerJoinEvent event)
|
|
{
|
|
final Player player = event.getPlayer();
|
|
final FPlayer fPlayer = plugin.pl.getPlayer(player);
|
|
final PlayerData playerData = plugin.pl.getData(player);
|
|
|
|
// Sends a message to the player if they have never joined before (or simply lack player data).
|
|
if (!event.getPlayer().hasPlayedBefore() && ConfigEntry.FIRST_JOIN_INFO_ENABLED.getBoolean())
|
|
{
|
|
new BukkitRunnable()
|
|
{
|
|
@Override
|
|
public void run()
|
|
{
|
|
ConfigEntry.FIRST_JOIN_INFO.getStringList().forEach(line -> FUtil.playerMsgCooler(player, line));
|
|
}
|
|
}.runTaskLater(plugin, 20);
|
|
}
|
|
|
|
FUtil.playerTitle(player, ConfigEntry.SERVER_LOGIN_TITLE.getString(), ConfigEntry.SERVER_LOGIN_SUBTITLE.getString());
|
|
|
|
if (TELEPORT_ON_JOIN.contains(player.getName()) || ConfigEntry.AUTO_TP.getBoolean())
|
|
{
|
|
int x = FUtil.randomInteger(-10000, 10000);
|
|
int z = FUtil.randomInteger(-10000, 10000);
|
|
int y = player.getWorld().getHighestBlockYAt(x, z) + 1;
|
|
Location location = new Location(player.getLocation().getWorld(), x, y, z);
|
|
PaperLib.teleportAsync(player, location);
|
|
FUtil.playerMsgCooler(player, "<aqua>You have been automatically teleported to a random location.");
|
|
return;
|
|
}
|
|
|
|
if (!playerData.getIps().contains(FUtil.getIp(player)))
|
|
{
|
|
playerData.addIp(FUtil.getIp(player));
|
|
plugin.pl.save(playerData);
|
|
}
|
|
|
|
if (CLEAR_ON_JOIN.contains(player.getName()) || ConfigEntry.AUTO_CLEAR.getBoolean())
|
|
{
|
|
player.getInventory().clear();
|
|
FUtil.playerMsgCooler(player, "<aqua>Your inventory has been automatically cleared.");
|
|
return;
|
|
}
|
|
|
|
if (!ConfigEntry.SERVER_TABLIST_HEADER.getString().isEmpty())
|
|
{
|
|
player.sendPlayerListHeader(FUtil.miniMessage(ConfigEntry.SERVER_TABLIST_HEADER.getString()));
|
|
}
|
|
|
|
if (!ConfigEntry.SERVER_TABLIST_FOOTER.getString().isEmpty())
|
|
{
|
|
player.sendPlayerListFooter(FUtil.miniMessage(ConfigEntry.SERVER_TABLIST_FOOTER.getString()));
|
|
}
|
|
|
|
if (!plugin.al.isAdmin(player))
|
|
{
|
|
Component tag = playerData.getTag();
|
|
if (tag != null)
|
|
{
|
|
fPlayer.setTag(tag);
|
|
}
|
|
|
|
int noteCount = playerData.getNotes().size();
|
|
if (noteCount != 0)
|
|
{
|
|
plugin.cm.messageAllAdmins("<gold>This player has <yellow><count> <gold>admin note<plural>.",
|
|
Placeholder.unparsed("count", String.valueOf(noteCount)), Placeholder.unparsed("plural", noteCount > 1 ? "s" : ""));
|
|
plugin.cm.messageAllAdmins("<gold>Do <yellow>/notes <player> list<gold> to view them.",
|
|
Placeholder.unparsed("player", player.getName()));
|
|
}
|
|
} else
|
|
{
|
|
Admin admin = plugin.al.getAdmin(player);
|
|
String format = admin.getAcFormat();
|
|
|
|
if (!Strings.isNullOrEmpty(format) && FConverter.needsConversion(admin.getAcFormat()))
|
|
{
|
|
player.sendMessage(FUtil.miniMessage("<green>Converting your admin chat format..."));
|
|
admin.setAcFormat(FConverter.convertAdminChatFormat(format));
|
|
plugin.al.save(admin);
|
|
}
|
|
}
|
|
|
|
new BukkitRunnable()
|
|
{
|
|
@Override
|
|
public void run()
|
|
{
|
|
if (ConfigEntry.ADMIN_ONLY_MODE.getBoolean())
|
|
{
|
|
FUtil.playerMsgCooler(player, "<red>Server is currently closed to non-admins.");
|
|
}
|
|
|
|
if (lockdownEnabled)
|
|
{
|
|
FUtil.playerMsgCooler(player, "<red>Warning: Server is currenty in lockdown-mode, new players will not be able to join!");
|
|
}
|
|
}
|
|
}.runTaskLater(plugin, 20L);
|
|
}
|
|
}
|