2024-03-26 09:00:12 +00:00
|
|
|
package cc.fascinated.account;
|
|
|
|
|
|
|
|
import cc.fascinated.Aetheria;
|
2024-04-03 15:11:36 +01:00
|
|
|
import cc.fascinated.account.command.SaveAccountsCommand;
|
2024-04-05 20:30:29 +01:00
|
|
|
import cc.fascinated.bot.DiscordBot;
|
|
|
|
import cc.fascinated.bot.DiscordChannel;
|
2024-04-03 15:11:36 +01:00
|
|
|
import cc.fascinated.command.CommandManager;
|
2024-04-01 12:34:28 +01:00
|
|
|
import cc.fascinated.config.Config;
|
|
|
|
import cc.fascinated.config.Lang;
|
2024-04-05 17:04:19 +01:00
|
|
|
import cc.fascinated.playercolor.PlayerColorProfile;
|
2024-03-26 09:00:12 +00:00
|
|
|
import cc.fascinated.utils.Manager;
|
2024-04-01 13:01:09 +01:00
|
|
|
import cc.fascinated.utils.Priority;
|
2024-04-01 12:34:28 +01:00
|
|
|
import cc.fascinated.utils.Style;
|
2024-04-03 15:11:36 +01:00
|
|
|
import com.viaversion.viaversion.api.Via;
|
2024-03-26 09:00:12 +00:00
|
|
|
import lombok.extern.log4j.Log4j2;
|
2024-04-05 20:30:29 +01:00
|
|
|
import net.dv8tion.jda.api.EmbedBuilder;
|
2024-04-05 21:43:32 +01:00
|
|
|
import net.kyori.adventure.text.Component;
|
2024-03-26 09:00:12 +00:00
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.entity.Player;
|
2024-04-01 13:01:09 +01:00
|
|
|
import org.bukkit.event.EventHandler;
|
|
|
|
import org.bukkit.event.Listener;
|
|
|
|
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
2024-03-26 09:00:12 +00:00
|
|
|
import org.bukkit.event.player.PlayerJoinEvent;
|
|
|
|
import org.bukkit.event.player.PlayerQuitEvent;
|
|
|
|
|
2024-04-05 20:30:29 +01:00
|
|
|
import java.awt.*;
|
|
|
|
import java.util.List;
|
2024-04-05 17:04:19 +01:00
|
|
|
import java.util.*;
|
2024-03-26 09:00:12 +00:00
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
@Log4j2
|
2024-04-01 13:01:09 +01:00
|
|
|
public class AccountManager extends Manager implements Listener {
|
2024-03-26 09:00:12 +00:00
|
|
|
|
2024-04-05 17:04:19 +01:00
|
|
|
private static final Map<UUID, Account> ACCOUNTS = new HashMap<>();
|
2024-04-05 17:07:57 +01:00
|
|
|
private final long SAVE_INTERVAL = 5; // in minutes
|
2024-03-26 09:00:12 +00:00
|
|
|
|
|
|
|
public AccountManager() {
|
2024-04-03 15:11:36 +01:00
|
|
|
CommandManager.registerCommand(new SaveAccountsCommand());
|
|
|
|
|
2024-04-01 13:01:09 +01:00
|
|
|
Aetheria.INSTANCE.getServer().getPluginManager().registerEvents(this, Aetheria.INSTANCE);
|
2024-03-26 09:00:12 +00:00
|
|
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
2024-04-05 17:04:19 +01:00
|
|
|
if (isAccountLoaded(player.getUniqueId())) { // Don't load the account if it's already loaded
|
|
|
|
continue;
|
|
|
|
}
|
2024-04-05 20:30:29 +01:00
|
|
|
loadAccount(player.getUniqueId(), player.getName());
|
2024-03-26 09:00:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Bukkit.getAsyncScheduler().runAtFixedRate(Aetheria.INSTANCE, (task) -> {
|
2024-04-03 15:11:36 +01:00
|
|
|
saveAccounts();
|
2024-03-29 17:46:05 +00:00
|
|
|
}, SAVE_INTERVAL, SAVE_INTERVAL, TimeUnit.MINUTES);
|
2024-03-26 09:00:12 +00:00
|
|
|
}
|
|
|
|
|
2024-04-05 20:30:29 +01:00
|
|
|
/**
|
|
|
|
* Gets a list of all online accounts.
|
|
|
|
*
|
|
|
|
* @return the online accounts
|
|
|
|
*/
|
|
|
|
public static List<Account> getOnlineAccounts() {
|
|
|
|
List<Account> accounts = new ArrayList<>();
|
|
|
|
for (Account account : ACCOUNTS.values()) {
|
|
|
|
if (account.isOnline()) {
|
|
|
|
accounts.add(account);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return accounts;
|
|
|
|
}
|
|
|
|
|
2024-03-26 09:00:12 +00:00
|
|
|
/**
|
|
|
|
* Gets the account for the specified player.
|
|
|
|
*
|
2024-04-01 13:01:09 +01:00
|
|
|
* @param uuid the player's UUID
|
2024-03-26 09:00:12 +00:00
|
|
|
* @return the account
|
|
|
|
*/
|
2024-04-01 13:01:09 +01:00
|
|
|
public static Account getAccount(UUID uuid) {
|
2024-04-05 17:04:19 +01:00
|
|
|
return ACCOUNTS.get(uuid);
|
2024-03-26 09:04:54 +00:00
|
|
|
}
|
|
|
|
|
2024-03-26 09:00:12 +00:00
|
|
|
/**
|
|
|
|
* Registers an account for the specified player.
|
|
|
|
*
|
2024-04-01 13:01:09 +01:00
|
|
|
* @param uuid the player's UUID
|
2024-04-05 20:30:29 +01:00
|
|
|
* @param name the player's name
|
2024-03-26 09:00:12 +00:00
|
|
|
*/
|
2024-04-05 20:30:29 +01:00
|
|
|
private static void loadAccount(UUID uuid, String name) {
|
|
|
|
Account account = new Account(uuid, name);
|
2024-03-26 09:04:54 +00:00
|
|
|
ACCOUNTS.put(uuid, account);
|
2024-03-26 09:00:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2024-04-05 17:04:19 +01:00
|
|
|
* Save dirty accounts to disk.
|
2024-03-26 09:00:12 +00:00
|
|
|
*/
|
2024-04-03 15:11:36 +01:00
|
|
|
public static void saveAccounts() {
|
|
|
|
long before = System.currentTimeMillis(),
|
|
|
|
saved = 0; // The amount of accounts that were saved
|
2024-03-26 09:00:12 +00:00
|
|
|
log.info("Saving accounts...");
|
2024-04-05 17:04:19 +01:00
|
|
|
List<Account> toRemove = new ArrayList<>();
|
|
|
|
for (Account account : ACCOUNTS.values()) {
|
2024-04-03 15:11:36 +01:00
|
|
|
boolean didSave = account.save(); // Save the account
|
|
|
|
if (didSave) {
|
|
|
|
saved++;
|
|
|
|
}
|
2024-04-05 17:04:19 +01:00
|
|
|
if (!account.isOnline()) {
|
|
|
|
toRemove.add(account);
|
|
|
|
}
|
2024-03-26 09:00:12 +00:00
|
|
|
}
|
2024-04-05 17:04:19 +01:00
|
|
|
toRemove.forEach(account -> ACCOUNTS.remove(account.getUuid())); // Unload offline accounts
|
2024-04-03 15:11:36 +01:00
|
|
|
log.info("Saved {}/{} accounts. ({}ms)", saved, ACCOUNTS.size(), System.currentTimeMillis() - before);
|
2024-03-26 09:00:12 +00:00
|
|
|
}
|
|
|
|
|
2024-04-05 21:43:32 +01:00
|
|
|
/**
|
|
|
|
* Deletes an account from the server.
|
|
|
|
* This will remove the account from memory and delete the account file.
|
|
|
|
*
|
|
|
|
* @param account the account to delete
|
|
|
|
*/
|
|
|
|
public void deleteAccount(Account account) {
|
|
|
|
account.getFile().delete();
|
|
|
|
ACCOUNTS.remove(account.getUuid());
|
|
|
|
|
|
|
|
account.getPlayer().kick(Component.text("Your account has been deleted. Please reconnect."));
|
|
|
|
log.info("Deleted account for {}", account.getUuid());
|
|
|
|
}
|
|
|
|
|
2024-04-05 17:07:57 +01:00
|
|
|
@Override
|
|
|
|
public Priority getPriority() {
|
|
|
|
return Priority.LOWEST;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if an account is already registered for the specified player.
|
|
|
|
*
|
|
|
|
* @param uuid the player's UUID
|
|
|
|
* @return true if the account is already registered, false otherwise
|
|
|
|
*/
|
|
|
|
private boolean isAccountLoaded(UUID uuid) {
|
|
|
|
return ACCOUNTS.containsKey(uuid);
|
|
|
|
}
|
|
|
|
|
2024-04-01 13:01:09 +01:00
|
|
|
@EventHandler
|
|
|
|
public void onAsyncPlayerPreLoginEvent(AsyncPlayerPreLoginEvent event) {
|
|
|
|
UUID uuid = event.getUniqueId();
|
2024-04-05 20:30:29 +01:00
|
|
|
String name = event.getName();
|
2024-04-01 13:01:09 +01:00
|
|
|
if (isAccountLoaded(uuid)) { // Account already loaded
|
|
|
|
return;
|
|
|
|
}
|
2024-04-05 20:30:29 +01:00
|
|
|
loadAccount(uuid, name); // Load the account into memory
|
2024-04-01 13:01:09 +01:00
|
|
|
}
|
|
|
|
|
2024-04-01 12:34:28 +01:00
|
|
|
@Override
|
|
|
|
public void onPlayerJoin(Account account, PlayerJoinEvent event) {
|
2024-04-01 12:46:15 +01:00
|
|
|
String joinMessage = Lang.JOIN_MESSAGE.getAsString();
|
2024-04-05 17:04:19 +01:00
|
|
|
PlayerColorProfile playerColorProfile = account.getPlayerColorProfile();
|
2024-04-01 12:46:15 +01:00
|
|
|
|
2024-04-03 15:11:36 +01:00
|
|
|
if (!account.getPlayer().hasPlayedBefore()) {
|
2024-04-01 12:46:15 +01:00
|
|
|
joinMessage = Lang.FIRST_JOIN_MESSAGE.getAsString();
|
|
|
|
|
2024-04-05 20:30:29 +01:00
|
|
|
DiscordBot.sendEmbed(DiscordChannel.PLAYER_LOGS, new EmbedBuilder()
|
|
|
|
.setThumbnail("https://crafatar.com/avatars/" + account.getUuid())
|
|
|
|
.setColor(Color.GREEN)
|
|
|
|
.setTitle("New Player Joined")
|
|
|
|
.addField("Player", account.getName(), true)
|
|
|
|
.addField("UUID", account.getUuid().toString(), true)
|
|
|
|
);
|
2024-03-26 09:00:12 +00:00
|
|
|
}
|
2024-04-01 12:46:15 +01:00
|
|
|
event.joinMessage(Style.getMiniMessage().deserialize(joinMessage
|
2024-04-03 15:11:36 +01:00
|
|
|
.replace("%player%", account.getName())
|
|
|
|
.replace("player-color", playerColorProfile.getColor().toString())
|
2024-04-01 12:34:28 +01:00
|
|
|
));
|
2024-04-03 15:11:36 +01:00
|
|
|
|
|
|
|
// Check if the player is using an outdated version and send a warning message
|
|
|
|
int version = Via.getAPI().getPlayerVersion(account.getUuid());
|
|
|
|
if (version < Config.VERSION_WARNING_VERSION.getAsInt()) {
|
|
|
|
account.sendMessage(Style.getMiniMessage().deserialize(Config.VERSION_WARNING_MESSAGE.getAsString()));
|
|
|
|
}
|
2024-03-26 09:00:12 +00:00
|
|
|
}
|
|
|
|
|
2024-04-01 12:34:28 +01:00
|
|
|
@Override
|
|
|
|
public void onPlayerQuit(Account account, PlayerQuitEvent event) {
|
2024-04-01 12:46:15 +01:00
|
|
|
event.quitMessage(Style.getMiniMessage().deserialize(Lang.QUIT_MESSAGE.getAsString()
|
|
|
|
.replace("%player%", event.getPlayer().getName())
|
|
|
|
.replace("player-color", account.getPlayerColorProfile().getColor().toString())
|
|
|
|
));
|
2024-04-01 12:34:28 +01:00
|
|
|
}
|
2024-03-26 09:00:12 +00:00
|
|
|
|
2024-04-01 12:34:28 +01:00
|
|
|
@Override
|
|
|
|
public void onAetheriaDisable() {
|
2024-04-03 15:11:36 +01:00
|
|
|
saveAccounts(); // Save the accounts to disk
|
2024-03-26 09:00:12 +00:00
|
|
|
}
|
|
|
|
}
|