diff --git a/.gitignore b/.gitignore
index 4be6607..2f7896d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,116 +1 @@
-# User-specific stuff
-.idea/
-
-*.iml
-*.ipr
-*.iws
-
-# IntelliJ
-out/
-
-# Compiled class file
-*.class
-
-# Log file
-*.log
-
-# BlueJ files
-*.ctxt
-
-# Mobile Tools for Java (J2ME)
-.mtj.tmp/
-
-# Package Files #
-*.jar
-*.war
-*.nar
-*.ear
-*.zip
-*.tar.gz
-*.rar
-
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
-hs_err_pid*
-
-*~
-
-# temporary files which can be created if a process still has a handle open of a deleted file
-.fuse_hidden*
-
-# KDE directory preferences
-.directory
-
-# Linux trash folder which might appear on any partition or disk
-.Trash-*
-
-# .nfs files are created when an open file is removed but is still being accessed
-.nfs*
-
-# General
-.DS_Store
-.AppleDouble
-.LSOverride
-
-# Icon must end with two \r
-Icon
-
-# Thumbnails
-._*
-
-# Files that might appear in the root of a volume
-.DocumentRevisions-V100
-.fseventsd
-.Spotlight-V100
-.TemporaryItems
-.Trashes
-.VolumeIcon.icns
-.com.apple.timemachine.donotpresent
-
-# Directories potentially created on remote AFP share
-.AppleDB
-.AppleDesktop
-Network Trash Folder
-Temporary Items
-.apdisk
-
-# Windows thumbnail cache files
-Thumbs.db
-Thumbs.db:encryptable
-ehthumbs.db
-ehthumbs_vista.db
-
-# Dump file
-*.stackdump
-
-# Folder config file
-[Dd]esktop.ini
-
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
-
-# Windows Installer files
-*.cab
-*.msi
-*.msix
-*.msm
-*.msp
-
-# Windows shortcuts
-*.lnk
-
target/
-
-pom.xml.tag
-pom.xml.releaseBackup
-pom.xml.versionsBackup
-pom.xml.next
-
-release.properties
-dependency-reduced-pom.xml
-buildNumber.properties
-.mvn/timing.properties
-.mvn/wrapper/maven-wrapper.jar
-.flattened-pom.xml
-
-# Common working directory
-run/
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..ab1f416
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,10 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Ignored default folder with query files
+/queries/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..58c1f83
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..eb46f0d
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ sqlite.xerial
+ true
+ org.sqlite.JDBC
+ jdbc:sqlite:$PROJECT_DIR$/../../../srv/smp/paper/plugins/SMPCore/smp.db
+ $ProjectFileDir$
+
+
+
\ No newline at end of file
diff --git a/.idea/data_source_mapping.xml b/.idea/data_source_mapping.xml
new file mode 100644
index 0000000..d67f041
--- /dev/null
+++ b/.idea/data_source_mapping.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..aa00ffa
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..07c9eb4
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..a2c176f
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..b83499c
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..7890b79
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
new file mode 100644
index 0000000..c5d1ee4
--- /dev/null
+++ b/.idea/sqldialects.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SMPCore.iml b/SMPCore.iml
new file mode 100644
index 0000000..93a6840
--- /dev/null
+++ b/SMPCore.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+ PAPER
+ ADVENTURE
+
+ 1
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/CachedProfile.java b/src/main/java/pro/cloudnode/smp/smpcore/CachedProfile.java
new file mode 100644
index 0000000..f92b74a
--- /dev/null
+++ b/src/main/java/pro/cloudnode/smp/smpcore/CachedProfile.java
@@ -0,0 +1,292 @@
+package pro.cloudnode.smp.smpcore;
+
+import com.destroystokyo.paper.profile.PlayerProfile;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import io.papermc.paper.plugin.configuration.PluginMeta;
+import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.Date;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Represents a player profile cached in the database.
+ *
+ * @param uuid UUID of the player.
+ * @param name Username of the player.
+ * @param fetched Date the profile was fetched from Mojang.
+ */
+@SuppressWarnings("ProfileCache")
+public record CachedProfile(@NotNull UUID uuid, @NotNull String name, @NotNull Date fetched) {
+ private static final @NotNull Duration MAX_AGE = Duration.ofDays(7);
+
+ static final @NotNull Duration STALE_WHILE_REVALIDATE = Duration.ofDays(1);
+
+ private static final @NotNull HttpClient client = HttpClient.newBuilder()
+ .connectTimeout(Duration.ofSeconds(15))
+ .build();
+
+ private static final @NotNull Logger logger = Logger
+ .getLogger(SMPCore.getInstance().getLogger().getName() + "/ProfileCache");
+
+ static {
+ logger.setParent(SMPCore.getInstance().getLogger());
+ }
+
+ /**
+ * Gets a cached profile by UUID.
+ *
+ * @param uuid UUID to look up in the database.
+ */
+ public static @NotNull Optional<@NotNull CachedProfile> getOffline(final @NotNull UUID uuid) {
+ try (final PreparedStatement stmt = SMPCore.getInstance().conn.prepareStatement(
+ "SELECT * FROM `cached_profiles` WHERE `uuid` = ? LIMIT 1"
+ )) {
+ stmt.setString(1, uuid.toString());
+
+ final ResultSet rs = stmt.executeQuery();
+ if (!rs.next())
+ return Optional.empty();
+
+ return Optional.<@NotNull CachedProfile>ofNullable(CachedProfile.from(rs));
+ }
+ catch (final SQLException e) {
+ logger.log(Level.SEVERE, "could not get profile for UUID " + uuid, e);
+ return Optional.empty();
+ }
+ }
+
+ /**
+ * Gets a cached profile for the specified OfflinePlayer.
+ *
+ * @param player OfflinePlayer to look up in the database.
+ */
+ public static @NotNull Optional<@NotNull CachedProfile> getOffline(final @NotNull OfflinePlayer player) {
+ return getOffline(player.getUniqueId());
+ }
+
+ /**
+ * Fetches a profile from Mojang and caches it.
+ *
+ * @param uuid UUID of the player to fetch.
+ */
+ private static @Nullable CachedProfile fetch(final @NotNull UUID uuid) {
+ logger.fine("Miss for UUID " + uuid);
+
+ final PluginMeta meta = SMPCore.getInstance().getPluginMeta();
+
+ final HttpRequest req = HttpRequest.newBuilder()
+ .uri(URI.create("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid.toString()))
+ .header("User-Agent", meta.getName() + "/" + meta.getVersion())
+ .GET()
+ .build();
+
+ try {
+ final HttpResponse res = client
+ .send(req, HttpResponse.BodyHandlers.ofString());
+
+ if (res.statusCode() >= 400 || res.statusCode() == 204 || res.statusCode() < 200 || res.body() == null) {
+ logger.log(Level.SEVERE, "got HTTP status " + res.statusCode()
+ + " for UUID " + uuid + ". Body is" + (res.body() == null ? "" : " not")
+ + " null.");
+ return null;
+ }
+
+ final JsonObject body = JsonParser.parseString(res.body()).getAsJsonObject();
+
+ return new CachedProfile(uuid, body.get("name").getAsString(), new Date())
+ .save();
+ }
+ catch (final IOException | InterruptedException e) {
+ logger.log(Level.SEVERE, "could not fetch profile for UUID " + uuid, e);
+ return null;
+ }
+ }
+
+ /**
+ * Fetches a profile from Mojang and caches it.
+ *
+ * @param player OfflinePlayer to fetch.
+ */
+ private static @Nullable CachedProfile fetch(final @NotNull OfflinePlayer player) {
+ return fetch(player.getUniqueId());
+ }
+
+ /**
+ * Gets a profile from the cache or fetches it from Mojang if cache stale or missed.
+ *
+ * @param uuid UUID of the player to fetch.
+ * @throws IllegalStateException if the profile could not be fetched.
+ */
+ public static @NotNull CachedProfile get(final @NotNull UUID uuid) throws IllegalStateException {
+ final @Nullable CachedProfile profile = getOffline(uuid).orElseGet(() -> fetch(uuid));
+
+ if (profile == null)
+ throw new IllegalStateException("profile for UUID " + uuid + " could not be fetched");
+
+ return profile;
+ }
+
+ /**
+ * Gets a profile from the cache or fetches it from Mojang if cache stale or missed.
+ * @param player OfflinePlayer to fetch.
+ * @throws IllegalStateException if the profile could not be fetched.
+ */
+ public static @NotNull CachedProfile get(final @NotNull OfflinePlayer player) throws IllegalStateException {
+ return get(player.getUniqueId());
+ }
+
+ /**
+ * Get OfflinePlayer by name if cached.
+ *
+ * @param name Username of the player to look up.
+ */
+ public static @Nullable OfflinePlayer getOffline(final @NotNull String name) {
+ final @Nullable OfflinePlayer player = Bukkit.getOfflinePlayerIfCached(name);
+ if (player != null)
+ return player;
+
+ try (final PreparedStatement stmt = SMPCore.getInstance().conn.prepareStatement(
+ "SELECT * from `cached_profiles` where `name` = ? LIMIT 1"
+ )) {
+ stmt.setString(1, name);
+
+ final ResultSet rs = stmt.executeQuery();
+ if (!rs.next())
+ return null;
+
+ final @Nullable CachedProfile profile = CachedProfile.from(rs);
+ if (profile == null)
+ return null;
+
+ return Bukkit.getOfflinePlayer(profile.uuid());
+ }
+ catch (final SQLException e) {
+ logger.log(Level.SEVERE, "could not get cached profile for name " + name, e);
+ return null;
+ }
+ }
+
+ /**
+ * Get OfflinePlayer by name, fetching from Mojang if necessary.
+ *
+ * @param name Username of the player to look up.
+ */
+ public static @NotNull OfflinePlayer get(final @NotNull String name) {
+ return Optional.<@NotNull OfflinePlayer>ofNullable(getOffline(name))
+ .orElseGet(() -> {
+ logger.fine("Miss for name " + name);
+ return Bukkit.getOfflinePlayer(name);
+ });
+ }
+
+ /**
+ * Deletes stale cached profiles.
+ */
+ public static void cleanUp() {
+ logger.fine("Cleaning up stale cached profiles...");
+ try (final @NotNull PreparedStatement stmt = SMPCore.getInstance().conn.prepareStatement(
+ "DELETE FROM `cached_profiles` WHERE `fetched` < ?"
+ )) {
+ stmt.setTimestamp(1, new Timestamp(staleWhileRevalidateThreshold().getTime()));
+ stmt.execute();
+ }
+ catch (final SQLException e) {
+ logger.log(Level.SEVERE, "could not clean up cached profiles", e);
+ }
+ }
+
+ public static @NotNull String getName(final @NotNull OfflinePlayer player) {
+ final @Nullable String name = player.getName();
+ if (name != null)
+ return name;
+
+ final PlayerProfile profile = player.getPlayerProfile();
+
+ if (profile.completeFromCache(true)) {
+ final @Nullable String profileName = profile.getName();
+ if (profileName != null && !profileName.isEmpty())
+ return profileName;
+ }
+
+ try {
+ return get(player).name();
+ }
+ catch (IllegalStateException e) {
+ logger.log(Level.SEVERE, "Failed to fetch", e);
+ return player.getUniqueId().toString();
+ }
+ }
+
+ private static @NotNull Date expirationThreshold() {
+ return new Date(System.currentTimeMillis() - MAX_AGE.toMillis());
+ }
+
+ private static @NotNull Date staleWhileRevalidateThreshold() {
+ return new Date(System.currentTimeMillis() - STALE_WHILE_REVALIDATE.toMillis() - MAX_AGE.toMillis());
+ }
+
+ private static @Nullable CachedProfile from(final ResultSet rs) throws SQLException {
+ final CachedProfile profile = new CachedProfile(
+ UUID.fromString(rs.getString("uuid")),
+ rs.getString("name"),
+ rs.getTimestamp("fetched")
+ );
+
+ if (profile.stale()) {
+ logger.fine("Profile cache is stale for " + profile.uuid + " ("
+ + Duration.between(profile.fetched.toInstant(), Instant.now()) + " old). Revalidation scheduled.");
+ SMPCore.runAsync(() -> CachedProfile.fetch(profile.uuid()));
+
+ if (profile.staleWhileRevalidate()) {
+ logger.fine("Serving stale cache for " + profile.uuid + " while revalidating.");
+ return profile;
+ }
+ return null;
+ }
+
+ return profile;
+ }
+
+ private boolean stale() {
+ return fetched.before(expirationThreshold());
+ }
+
+ private boolean staleWhileRevalidate() {
+ return fetched.before(staleWhileRevalidateThreshold());
+ }
+
+ private @NotNull CachedProfile save() {
+ SMPCore.runAsync(() -> {
+ try (final PreparedStatement stmt = SMPCore.getInstance().conn.prepareStatement(
+ "INSERT OR REPLACE INTO `cached_profiles` (`uuid`, `name`, `fetched`) VALUES (?, ?, ?)"
+ )) {
+ stmt.setString(1, uuid().toString());
+ stmt.setString(2, name());
+ stmt.setTimestamp(3, new Timestamp(fetched().getTime()));
+ stmt.executeUpdate();
+ } catch (final SQLException e) {
+ logger.log(Level.SEVERE, "could not save profile for UUID " + uuid, e);
+ }
+ });
+
+ return this;
+ }
+}
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/Configuration.java b/src/main/java/pro/cloudnode/smp/smpcore/Configuration.java
index e85a0c8..0cb9091 100644
--- a/src/main/java/pro/cloudnode/smp/smpcore/Configuration.java
+++ b/src/main/java/pro/cloudnode/smp/smpcore/Configuration.java
@@ -7,7 +7,6 @@
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
@@ -114,9 +113,7 @@ public boolean deathBanEnabled() {
}
public void staffCommands(final boolean addMode, final @NotNull OfflinePlayer player) {
- final @Nullable String name = player.getName();
- if (name == null)
- return;
+ final String name = CachedProfile.getName(player);
final List commands = config.getStringList("staff.commands." + (addMode ? "add" : "remove"));
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/Member.java b/src/main/java/pro/cloudnode/smp/smpcore/Member.java
index e28b760..0ed8602 100644
--- a/src/main/java/pro/cloudnode/smp/smpcore/Member.java
+++ b/src/main/java/pro/cloudnode/smp/smpcore/Member.java
@@ -13,7 +13,6 @@
import java.sql.SQLException;
import java.util.Date;
import java.util.HashSet;
-import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
@@ -82,7 +81,8 @@ public boolean isAlt() {
while (rs.next()) alts.add(new Member(rs));
}
catch (final @NotNull SQLException e) {
- SMPCore.getInstance().getLogger().log(Level.SEVERE, "could not get alts for " + player().getName(), e);
+ SMPCore.getInstance().getLogger().log(Level.SEVERE, "could not get alts for "
+ + CachedProfile.getName(player()), e);
}
return alts;
@@ -248,14 +248,17 @@ public static int count() {
}
}
- @SuppressWarnings("NullableProblems")
public static @NotNull Set<@NotNull String> getNames() {
- return get().stream().map(m -> m.player().getName()).filter(Objects::nonNull).collect(Collectors.toSet());
+ return get().stream()
+ .map(m -> CachedProfile.getName(m.player()))
+ .collect(Collectors.toSet());
}
- @SuppressWarnings("NullableProblems")
public static @NotNull Set<@NotNull String> getAltNames() {
- return get().stream().filter(Member::isAlt).map(m -> m.player().getName()).filter(Objects::nonNull).collect(Collectors.toSet());
+ return get().stream()
+ .filter(Member::isAlt)
+ .map(m -> CachedProfile.getName(m.player()))
+ .collect(Collectors.toSet());
}
public static @NotNull Team createStaffTeam() {
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/Messages.java b/src/main/java/pro/cloudnode/smp/smpcore/Messages.java
index c94aeec..4cd3357 100644
--- a/src/main/java/pro/cloudnode/smp/smpcore/Messages.java
+++ b/src/main/java/pro/cloudnode/smp/smpcore/Messages.java
@@ -36,12 +36,17 @@ public Messages() {
}
public @NotNull Component reloaded() {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("reloaded")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("reloaded"))
+ );
}
public @NotNull Component usage(final @NotNull String label, final @NotNull String args) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("usage")), Placeholder.unparsed("label", label), Placeholder.unparsed("args", args));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("usage")),
+ Placeholder.unparsed("label", label),
+ Placeholder.unparsed("args", args)
+ );
}
private @NotNull Component formatDuration(@Nullable Duration duration) {
@@ -66,25 +71,18 @@ public Messages() {
}
public @NotNull Component bannedPlayer(final @NotNull OfflinePlayer player, final @Nullable Duration duration) {
- return MiniMessage.miniMessage()
- .deserialize(
- Objects.requireNonNull(config.getString("banned-player")),
- Placeholder.unparsed("player",
- Optional.ofNullable(player.getName())
- .orElse(player.getUniqueId().toString())
- ),
- Placeholder.component("duration", formatDuration(duration))
- );
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("banned-player")),
+ Placeholder.unparsed("player", CachedProfile.getName(player)),
+ Placeholder.component("duration", formatDuration(duration))
+ );
}
public @NotNull Component bannedMember(final @NotNull Member member, final @Nullable Duration duration) {
return MiniMessage.miniMessage()
.deserialize(
Objects.requireNonNull(config.getString("banned-member")),
- Placeholder.unparsed("player",
- Optional.ofNullable(member.player().getName())
- .orElse(member.player().getUniqueId().toString())
- ),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player())),
Placeholder.component("duration", formatDuration(duration))
);
}
@@ -94,16 +92,14 @@ public Messages() {
final @NotNull List<@NotNull Member> alts,
final @Nullable Duration duration
) {
- final @NotNull String altsString = alts.stream()
- .map(m -> Optional.ofNullable(m.player().getName()).orElse(m.player().getUniqueId().toString()))
+ final String altsString = alts.stream()
+ .map(m -> CachedProfile.getName(m.player()))
.collect(Collectors.joining(", "));
+
return MiniMessage.miniMessage()
.deserialize(
Objects.requireNonNull(config.getString("banned-member-chain")),
- Placeholder.unparsed("player",
- Optional.ofNullable(member.player().getName())
- .orElse(member.player().getUniqueId().toString())
- ),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player())),
Placeholder.unparsed("n-alt", String.valueOf(alts.size())),
Placeholder.unparsed("alts", altsString),
Placeholder.component("duration", formatDuration(duration))
@@ -111,92 +107,135 @@ public Messages() {
}
public @NotNull Component unbannedPlayer(final @NotNull OfflinePlayer player) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("unbanned-player")), Placeholder.unparsed("player", Optional
- .ofNullable(player.getName()).orElse(player.getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("unbanned-player")),
+ Placeholder.unparsed("player", CachedProfile.getName(player))
+ );
}
public @NotNull Component unbannedMember(final @NotNull Member member, final @NotNull List<@NotNull Member> alts) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("unbanned-member")), Placeholder.unparsed("player", Optional
- .ofNullable(member.player().getName()).orElse(member.player().getUniqueId()
- .toString())), Placeholder.unparsed("n-alts", String.valueOf(alts.size())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("unbanned-member")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player())),
+ Placeholder.unparsed("n-alts", String.valueOf(alts.size()))
+ );
}
// subcommands
public @NotNull Component subCommandHeader(final @NotNull String name, final @NotNull String usage) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("subcommands.header")), Placeholder.unparsed("name", name), Placeholder.unparsed("usage", usage));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("subcommands.header")),
+ Placeholder.unparsed("name", name),
+ Placeholder.unparsed("usage", usage)
+ );
}
- public @NotNull Component subCommandEntry(final @NotNull String command, final @NotNull String label, final @NotNull SubCommandArgument @NotNull [] args) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("subcommands.entry"))
- .replace("", command), Placeholder.unparsed("label", label), Placeholder.component("args", SubCommandArgument.join(args)));
+ public @NotNull Component subCommandEntry(
+ final @NotNull String command,
+ final @NotNull String label,
+ final @NotNull SubCommandArgument @NotNull [] args
+ ) {
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("subcommands.entry")).replace("", command),
+ Placeholder.unparsed("label", label),
+ Placeholder.component("args", SubCommandArgument.join(args))
+ );
}
public @NotNull Component subCommandEntry(final @NotNull String command, final @NotNull String label) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("subcommands.entry"))
- .replace("", command), Placeholder.unparsed("label", label), Placeholder.component("args", SubCommandArgument.join(SubCommandArgument.of())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("subcommands.entry")).replace("", command),
+ Placeholder.unparsed("label", label),
+ Placeholder.component("args", SubCommandArgument.join(SubCommandArgument.of()))
+ );
}
- public @NotNull Component subCommandEntry(final @NotNull String command, final @NotNull String label, final @NotNull SubCommandArgument @NotNull [] args, final @NotNull String description) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("subcommands.entry-with-description"))
- .replace("", command), Placeholder.unparsed("label", label), Placeholder.component("args", SubCommandArgument.join(args)), Placeholder.unparsed("description", description));
+ public @NotNull Component subCommandEntry(
+ final @NotNull String command,
+ final @NotNull String label,
+ final @NotNull SubCommandArgument @NotNull [] args,
+ final @NotNull String description
+ ) {
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("subcommands.entry-with-description"))
+ .replace("", command),
+ Placeholder.unparsed("label", label),
+ Placeholder.component("args", SubCommandArgument.join(args)),
+ Placeholder.unparsed("description", description)
+ );
}
- public @NotNull Component subCommandEntry(final @NotNull String command, final @NotNull String label, final @NotNull String description) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("subcommands.entry-with-description"))
- .replace("", command), Placeholder.unparsed("label", label), Placeholder.component("args", SubCommandArgument.join(SubCommandArgument.of())), Placeholder.unparsed("description", description));
+ public @NotNull Component subCommandEntry(
+ final @NotNull String command,
+ final @NotNull String label,
+ final @NotNull String description
+ ) {
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("subcommands.entry-with-description"))
+ .replace("", command),
+ Placeholder.unparsed("label", label),
+ Placeholder.component("args", SubCommandArgument.join(SubCommandArgument.of())),
+ Placeholder.unparsed("description", description)
+ );
}
public @NotNull Component subCommandArgumentRequired(final @NotNull String argument) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("subcommands.argument.required")), Placeholder.unparsed("arg", argument));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("subcommands.argument.required")),
+ Placeholder.unparsed("arg", argument)
+ );
}
public @NotNull Component subCommandArgumentOptional(final @NotNull String argument) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("subcommands.argument.optional")), Placeholder.unparsed("arg", argument));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("subcommands.argument.optional")),
+ Placeholder.unparsed("arg", argument)
+ );
}
// end of subcommands
public @NotNull Component altsListHeader(final @NotNull Member member) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("alts.list.header")), Placeholder.unparsed("player", Optional
- .ofNullable(member.player().getName()).orElse(member.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("alts.list.header")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component altsListNone() {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("alts.list.none")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("alts.list.none"))
+ );
}
public @NotNull Component altsListEntry(final @NotNull Member alt) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("alts.list.entry")), Placeholder.unparsed("alt", Optional
- .ofNullable(alt.player().getName()).orElse(alt.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("alts.list.entry")),
+ Placeholder.unparsed("alt", CachedProfile.getName(alt.player()))
+ );
}
public @NotNull Component altsConfirmAdd(final @NotNull OfflinePlayer alt, final @NotNull String confirmCommand) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("alts.confirm-add")).replace("", confirmCommand), Placeholder.unparsed("alt", Optional
- .ofNullable(alt.getName()).orElse(alt.getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("alts.confirm-add"))
+ .replace("", confirmCommand),
+ Placeholder.unparsed("alt", CachedProfile.getName(alt))
+ );
}
public @NotNull Component altsCreated(final @NotNull Member alt) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("alts.created")), Placeholder.unparsed("alt", Optional
- .ofNullable(alt.player().getName()).orElse(alt.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("alts.created")),
+ Placeholder.unparsed("alt", CachedProfile.getName(alt.player()))
+ );
}
public @NotNull Component altsDeleted(final @NotNull Member alt) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("alts.deleted")), Placeholder.unparsed("alt", Optional
- .ofNullable(alt.player().getName()).orElse(alt.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("alts.deleted")),
+ Placeholder.unparsed("alt", CachedProfile.getName(alt.player()))
+ );
}
public @NotNull Component membersNationlessFallback() {
@@ -220,8 +259,7 @@ public Messages() {
public @NotNull Component membersListEntry(final @NotNull Member member) {
return MiniMessage.miniMessage().deserialize(
Objects.requireNonNull(config.getString("members.list.entry")),
- Placeholder.unparsed("player", Optional.ofNullable(member.player().getName())
- .orElse(member.player().getUniqueId().toString())),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player())),
Formatter.choice("staff", member.staff ? 1 : 0),
Placeholder.component("nation", member.nation()
.map(n -> n.getTeam().displayName())
@@ -234,463 +272,593 @@ public Messages() {
public @NotNull Component membersAdded(final @NotNull Member member) {
return MiniMessage.miniMessage().deserialize(
Objects.requireNonNull(config.getString("members.added")),
- Placeholder.unparsed("player", Optional.ofNullable(member.player().getName())
- .orElse(member.player().getUniqueId().toString()))
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
);
}
public @NotNull Component membersDeleted(final @NotNull OfflinePlayer player) {
return MiniMessage.miniMessage().deserialize(
Objects.requireNonNull(config.getString("members.deleted")),
- Placeholder.unparsed("player", Optional.ofNullable(player.getName())
- .orElse(player.getUniqueId().toString()))
+ Placeholder.unparsed("player", CachedProfile.getName(player))
);
}
public @NotNull Component membersSetStaff(final @NotNull Member member) {
return MiniMessage.miniMessage().deserialize(
Objects.requireNonNull(config.getString("members.set-staff")),
- Placeholder.unparsed("player", Optional.ofNullable(member.player().getName())
- .orElse(member.player().getUniqueId().toString())),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player())),
Formatter.choice("staff", member.staff ? 1 : 0)
);
}
public @NotNull Component seen(final @NotNull Member member) {
- if (member.player().isOnline()) return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("seen.online")), Placeholder.unparsed("player", Optional
- .ofNullable(member.player().getName()).orElse(member.uuid.toString())));
- final @NotNull Date lastSeen = new Date(member.player().getLastSeen());
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString(member.isActive() ? "seen.active" : "seen.inactive")), Placeholder.unparsed("player", Optional
- .ofNullable(member.player().getName())
- .orElse(member.uuid.toString())), Formatter.date("last-seen", lastSeen.toInstant()
- .atZone(ZoneOffset.UTC)
- .toLocalDateTime()), Placeholder.component("last-seen-relative", SMPCore.relativeTime(lastSeen)));
+ if (member.player().isOnline()) return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("seen.online")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
+
+ final Date lastSeen = new Date(member.player().getLastSeen());
+
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString(member.isActive() ? "seen.active" : "seen.inactive")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player())),
+ Formatter.date("last-seen", lastSeen.toInstant().atZone(ZoneOffset.UTC).toLocalDateTime()),
+ Placeholder.component("last-seen-relative", SMPCore.relativeTime(lastSeen))
+ );
}
public @NotNull Component seen(final @NotNull OfflinePlayer player) {
- if (player.isOnline()) return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("seen.online")), Placeholder.unparsed("player", Optional
- .ofNullable(player.getName()).orElse(player.getUniqueId().toString())));
- final @NotNull Date lastSeen = new Date(player.getLastSeen());
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("seen.non-member")), Placeholder.unparsed("player", Optional
- .ofNullable(player.getName())
- .orElse(player.getUniqueId().toString())), Formatter.date("last-seen", lastSeen.toInstant()
- .atZone(ZoneOffset.UTC)
- .toLocalDateTime()), Placeholder.component("last-seen-relative", SMPCore.relativeTime(lastSeen)));
+ if (player.isOnline())
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("seen.online")),
+ Placeholder.unparsed("player", CachedProfile.getName(player))
+ );
+
+ final Date lastSeen = new Date(player.getLastSeen());
+
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("seen.non-member")),
+ Placeholder.unparsed("player", CachedProfile.getName(player)),
+ Formatter.date("last-seen", lastSeen.toInstant().atZone(ZoneOffset.UTC).toLocalDateTime()),
+ Placeholder.component("last-seen-relative", SMPCore.relativeTime(lastSeen))
+ );
}
public @NotNull Component time(final @NotNull Date date) {
- final @NotNull Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ final Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTime(date);
+
final int day = calendar.get(Calendar.DAY_OF_MONTH);
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("time")), Formatter.date("date", calendar
- .toInstant().atZone(ZoneOffset.UTC)
- .toLocalDateTime()), Placeholder.unparsed("day", String.valueOf(day)), Placeholder.unparsed("day", String.valueOf(day)), Formatter.choice("day-format", day));
+
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("time")),
+ Formatter.date("date", calendar.toInstant().atZone(ZoneOffset.UTC).toLocalDateTime()),
+ Placeholder.unparsed("day", String.valueOf(day)),
+ Placeholder.unparsed("day", String.valueOf(day)),
+ Formatter.choice("day-format", day)
+ );
}
public @NotNull Component nationCitizensStatus(final @NotNull Member member) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString(member.isActive() ? "nation.citizens.status.active" : "nation.citizens.status.inactive")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString(member.isActive()
+ ? "nation.citizens.status.active"
+ : "nation.citizens.status.inactive"))
+ );
}
- public @NotNull Component nationCitizensList(final @NotNull Nation nation, final @NotNull Permissible sender, final boolean other) {
- final @NotNull Set<@NotNull Member> members = nation.citizens();
- final @NotNull Component header = MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.list.header"))
+ public @NotNull Component nationCitizensList(
+ final @NotNull Nation nation,
+ final @NotNull Permissible sender,
+ final boolean other
+ ) {
+ final Set members = nation.citizens();
+
+ final Component header = MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.citizens.list.header"))
.replaceAll("", "<#" + nation.color + ">")
.replaceAll("", "#" + nation.color + ">"),
- Placeholder.unparsed("nation-name", nation.name),
- Placeholder.unparsed("nation-active-members", members.stream().filter(Member::isActive).count() + ""),
- Placeholder.unparsed("nation-inactive-members", members.stream().filter(m -> !m.isActive()).count() + ""),
- Placeholder.unparsed("nation-total-members", members.size() + "")
- );
+ Placeholder.unparsed("nation-name", nation.name),
+ Placeholder.unparsed("nation-active-members", String.valueOf(members.stream()
+ .filter(Member::isActive)
+ .count()
+ )),
+ Placeholder.unparsed("nation-inactive-members", String.valueOf(members.stream()
+ .filter(m -> !m.isActive())
+ .count()
+ )),
+ Placeholder.unparsed("nation-total-members", String.valueOf(members.size()))
+ );
+
+ final List list = new ArrayList<>();
- final @NotNull List<@NotNull Component> list = new ArrayList<>();
+ final Member leader = members.stream()
+ .filter(m -> m.uuid.equals(nation.leaderUUID))
+ .findFirst()
+ .orElseThrow(IllegalStateException::new);
- final @NotNull Member leader = members.stream().filter(m -> m.uuid.equals(nation.leaderUUID)).findFirst().orElseThrow(IllegalStateException::new);
list.add(nationCitizensListEntry(nation, leader, sender, other));
- final @NotNull Member vice = members.stream().filter(m -> m.uuid.equals(nation.viceLeaderUUID)).findFirst().orElseThrow(IllegalStateException::new);
+ final Member vice = members.stream()
+ .filter(m -> m.uuid.equals(nation.viceLeaderUUID))
+ .findFirst()
+ .orElseThrow(IllegalStateException::new);
+
if (!vice.uuid.equals(leader.uuid))
list.add(nationCitizensListEntry(nation, vice, sender, other));
- final @NotNull List<@NotNull Component> citizens = members.stream().filter(m -> !m.uuid.equals(leader.uuid) && !m.uuid.equals(vice.uuid) && m.isActive()).map(m -> nationCitizensListEntry(nation, m, sender, other)).toList();
+ final List citizens = members.stream()
+ .filter(m -> !m.uuid.equals(leader.uuid) && !m.uuid.equals(vice.uuid) && m.isActive())
+ .map(m -> nationCitizensListEntry(nation, m, sender, other))
+ .toList();
+
list.addAll(citizens);
- final @NotNull List<@NotNull Component> inactive = members.stream().filter(m -> !m.uuid.equals(leader.uuid) && !m.uuid.equals(vice.uuid) && !m.isActive()).map(m -> nationCitizensListEntry(nation, m, sender, other)).toList();
+ final List inactive = members.stream()
+ .filter(m -> !m.uuid.equals(leader.uuid) && !m.uuid.equals(vice.uuid) && !m.isActive())
+ .map(m -> nationCitizensListEntry(nation, m, sender, other))
+ .toList();
+
list.addAll(inactive);
- final @NotNull TextComponent.Builder listComponent = Component.text();
- for (int i = 0; i < list.size(); i++) {
+ final TextComponent.Builder listComponent = Component.text();
+
+ for (int i = 0; i < list.size(); ++i) {
listComponent.append(list.get(i));
- if (i + 1 < list.size()) listComponent.append(Component.newline());
+
+ if (i + 1 < list.size())
+ listComponent.append(Component.newline());
}
- return Component.text().append(header).append(Component.newline()).append(listComponent.build()).build();
+ return Component.text()
+ .append(header)
+ .append(Component.newline())
+ .append(listComponent.build())
+ .build();
}
- private @NotNull Component nationCitizensListEntry(final @NotNull Nation nation, final @NotNull Member member, final @NotNull Permissible sender, final boolean other) {
- if (member.uuid.equals(nation.leaderUUID)) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.list.entry.leader"))
- .replaceAll("", "<#" + nation.color + ">")
- .replaceAll("", "#" + nation.color + ">")
- .replaceAll("", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())),
- Placeholder.component("member-status", nationCitizensStatus(member)),
- Placeholder.component("buttons", nationCitizensListButtons(nation, member, sender, other))
- );
- }
- if (member.uuid.equals(nation.viceLeaderUUID)) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.list.entry.vice"))
- .replaceAll("", "<#" + nation.color + ">")
- .replaceAll("", "#" + nation.color + ">")
- .replaceAll("", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())),
- Placeholder.component("member-status", nationCitizensStatus(member)),
- Placeholder.component("buttons", nationCitizensListButtons(nation, member, sender, other))
- );
- }
- if (member.isActive()) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.list.entry.citizen"))
- .replaceAll("", "<#" + nation.color + ">")
- .replaceAll("", "#" + nation.color + ">")
- .replaceAll("", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())),
- Placeholder.component("member-status", nationCitizensStatus(member)),
- Placeholder.component("buttons", nationCitizensListButtons(nation, member, sender, other))
- );
- }
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.list.entry.inactive-citizen"))
- .replaceAll("", "<#" + nation.color + ">")
- .replaceAll("", "#" + nation.color + ">")
- .replaceAll("", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())),
- Placeholder.component("member-status", nationCitizensStatus(member)),
- Placeholder.component("buttons", nationCitizensListButtons(nation, member, sender, other))
- );
+ private @NotNull Component nationCitizensListEntry(
+ final @NotNull Nation nation,
+ final @NotNull Member member,
+ final @NotNull Permissible sender,
+ final boolean other
+ ) {
+ final String configKey;
+
+ if (member.uuid.equals(nation.leaderUUID))
+ configKey = "nation.citizens.list.entry.leader";
+ else if (member.uuid.equals(nation.viceLeaderUUID))
+ configKey = "nation.citizens.list.entry.vice";
+ else if (member.isActive())
+ configKey = "nation.citizens.list.entry.citizen";
+ else
+ configKey = "nation.citizens.list.entry.inactive-citizen";
+
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString(configKey))
+ .replaceAll("", "<#" + nation.color + ">")
+ .replaceAll("", "#" + nation.color + ">")
+ .replaceAll("", CachedProfile.getName(member.player())),
+ Placeholder.component("member-status", nationCitizensStatus(member)),
+ Placeholder.component("buttons", nationCitizensListButtons(nation, member, sender, other))
+ );
}
- private @NotNull Component nationCitizensListButtons(final @NotNull Nation nation, final @NotNull Member member, final @NotNull Permissible sender, final boolean other) {
- final @NotNull List<@NotNull Component> buttons = new ArrayList<>();
- if (
- ((!other && sender.hasPermission(Permission.NATION_CITIZENS_KICK))
- || sender.hasPermission(Permission.NATION_CITIZENS_KICK_OTHER))
- && !(member.uuid.equals(nation.leaderUUID) || member.uuid.equals(nation.viceLeaderUUID))
- )
+ private @NotNull Component nationCitizensListButtons(
+ final @NotNull Nation nation,
+ final @NotNull Member member,
+ final @NotNull Permissible sender,
+ final boolean other
+ ) {
+ final List buttons = new ArrayList<>();
+
+ final boolean canKick = (!other && sender.hasPermission(Permission.NATION_CITIZENS_KICK)) ||
+ sender.hasPermission(Permission.NATION_CITIZENS_KICK_OTHER);
+ final boolean canDemote = (!other && sender.hasPermission(Permission.NATION_DEMOTE)) ||
+ sender.hasPermission(Permission.NATION_DEMOTE_OTHER);
+ final boolean canPromote = (!other && sender.hasPermission(Permission.NATION_PROMOTE)) ||
+ sender.hasPermission(Permission.NATION_PROMOTE_OTHER);
+
+ final boolean isLeader = member.uuid.equals(nation.leaderUUID);
+ final boolean isVice = member.uuid.equals(nation.viceLeaderUUID);
+ final boolean hasVice = !nation.viceLeaderUUID.equals(nation.leaderUUID);
+
+ if (canKick && !isLeader && !isVice)
buttons.add(nationCitizensListButton("kick", nation, member));
- if (
- ((!other && sender.hasPermission(Permission.NATION_DEMOTE))
- || sender.hasPermission(Permission.NATION_DEMOTE_OTHER))
- && member.uuid.equals(nation.viceLeaderUUID)
- )
+
+ if (canDemote && isVice)
buttons.add(nationCitizensListButton("demote", nation, member));
- if (
- ((!other && sender.hasPermission(Permission.NATION_PROMOTE))
- || sender.hasPermission(Permission.NATION_PROMOTE_OTHER))
- && nation.viceLeaderUUID.equals(nation.leaderUUID)
- && !member.uuid.equals(nation.leaderUUID)
- && member.isActive()
- )
+ if (canPromote && !hasVice && !isLeader && member.isActive())
buttons.add(nationCitizensListButton("promote", nation, member));
- final @NotNull TextComponent.Builder buttonsComponent = Component.text();
- if (!buttons.isEmpty()) buttonsComponent.append(MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("nation.citizens.list.buttons.prefix"))));
- for (int i = 0; i < buttons.size(); i++) {
+ final TextComponent.Builder buttonsComponent = Component.text();
+
+ if (!buttons.isEmpty()) buttonsComponent.append(MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.citizens.list.buttons.prefix"))
+ ));
+
+ for (int i = 0; i < buttons.size(); ++i) {
buttonsComponent.append(buttons.get(i));
- if (i + 1 < buttons.size()) buttonsComponent.append(MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("nation.citizens.list.buttons.separator"))));
+
+ if (i + 1 < buttons.size())
+ buttonsComponent.append(MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.citizens.list.buttons.separator"))
+ ));
}
- if (!buttons.isEmpty()) buttonsComponent.append(MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("nation.citizens.list.buttons.suffix"))));
- return Component.text().append(buttonsComponent.build()).build();
+ if (!buttons.isEmpty())
+ buttonsComponent.append(MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.citizens.list.buttons.suffix"))
+ ));
+
+ return Component.text()
+ .append(buttonsComponent.build())
+ .build();
}
- private @NotNull Component nationCitizensListButton(final @NotNull String button, final @NotNull Nation nation, final @NotNull Member member) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.list.buttons." + button))
- .replaceAll("", "<#" + nation.color + ">")
- .replaceAll("", "#" + nation.color + ">")
- .replaceAll("", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())));
+ private @NotNull Component nationCitizensListButton(
+ final @NotNull String button,
+ final @NotNull Nation nation,
+ final @NotNull Member member
+ ) {
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.citizens.list.buttons." + button))
+ .replaceAll("", "<#" + nation.color + ">")
+ .replaceAll("", "#" + nation.color + ">")
+ .replaceAll("", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component nationCitizensKicked(final @NotNull Member member) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.kicked")), Placeholder.unparsed("player", Optional
- .ofNullable(member.player().getName()).orElse(member.uuid.toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.citizens.kicked")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component nationCitizensVicePromoted(final @NotNull Member member) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.vice.promoted")), Placeholder.unparsed("player", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.citizens.vice.promoted")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component nationCitizensVicePromoted() {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.vice.promoted-you")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.citizens.vice.promoted-you"))
+ );
}
public @NotNull Component nationCitizensViceDemoted(final @NotNull Member member) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.vice.demoted")), Placeholder.unparsed("player", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.citizens.vice.demoted")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component nationCitizensViceDemoted() {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.citizens.vice.demoted-you")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.citizens.vice.demoted-you"))
+ );
}
public @NotNull Component nationJoinRequestSent(final @NotNull Nation nation) {
- return MiniMessage.miniMessage()
- .deserialize(
- Objects.requireNonNull(config.getString("nation.join.request-sent"))
- .replaceAll("", nation.id),
- Placeholder.unparsed("nation", nation.name)
- );
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.join.request-sent"))
+ .replaceAll("", nation.id),
+ Placeholder.unparsed("nation", nation.name)
+ );
}
public @NotNull Component nationJoinRequestReceived(final @NotNull Member member) {
- return MiniMessage.miniMessage()
- .deserialize(
- Objects.requireNonNull(config.getString("nation.join.request-received"))
- .replaceAll("", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString()))
- );
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.join.request-received"))
+ .replaceAll("", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component nationJoinInviteSent(final @NotNull Member member) {
- return MiniMessage.miniMessage()
- .deserialize(
- Objects.requireNonNull(config.getString("nation.join.invite-sent"))
- .replaceAll("", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString()))
- );
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.join.invite-sent"))
+ .replaceAll("", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component nationJoinInviteReceived(final @NotNull Nation nation) {
- return MiniMessage.miniMessage()
- .deserialize(
- Objects.requireNonNull(config.getString("nation.join.invite-received"))
- .replaceAll("", nation.id),
- Placeholder.unparsed("nation", nation.name)
- );
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.join.invite-received"))
+ .replaceAll("", nation.id),
+ Placeholder.unparsed("nation", nation.name)
+ );
}
public @NotNull Component nationJoinJoined(final @NotNull Member member) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.join.joined")), Placeholder.unparsed("player", Optional
- .ofNullable(member.player().getName()).orElse(member.uuid.toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.join.joined")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component nationJoinLeft(final @NotNull Member member) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.join.left")), Placeholder.unparsed("player", Optional
- .ofNullable(member.player().getName()).orElse(member.uuid.toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.join.left")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component nationJoinRequestCancelled(final @NotNull Nation nation) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("nation.join.request-cancelled")), Placeholder.unparsed("nation", nation.name));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.join.request-cancelled")),
+ Placeholder.unparsed("nation", nation.name)
+ );
}
public @NotNull Component nationJoinRequestRejected(final @NotNull Member member, final @NotNull Nation nation) {
- return MiniMessage.miniMessage()
- .deserialize(
- Objects.requireNonNull(config.getString("nation.join.request-rejected")),
- Placeholder.unparsed("player", Optional.ofNullable(
- member.player().getName()).orElse(member.uuid.toString())
- ),
- Placeholder.unparsed("nation", nation.name)
- );
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.join.request-rejected")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player())),
+ Placeholder.unparsed("nation", nation.name)
+ );
}
public @NotNull Component nationJoinInviteCancelled(final @NotNull Member member, final @NotNull Nation nation) {
- return MiniMessage.miniMessage()
- .deserialize(
- Objects.requireNonNull(config.getString("nation.join.invite-cancelled")),
- Placeholder.unparsed("player", Optional.ofNullable(
- member.player().getName()).orElse(member.uuid.toString())
- ),
- Placeholder.unparsed("nation", nation.name)
- );
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.join.invite-cancelled")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player())),
+ Placeholder.unparsed("nation", nation.name)
+ );
}
public @NotNull Component nationJoinInviteRejected(final @NotNull Nation nation) {
- return MiniMessage.miniMessage()
- .deserialize(
- Objects.requireNonNull(config.getString("nation.join.invite-rejected")),
- Placeholder.unparsed("nation", nation.name)
- );
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("nation.join.invite-rejected")),
+ Placeholder.unparsed("nation", nation.name)
+ );
}
public @NotNull Optional<@NotNull Component> banScreen(final @NotNull BanEntry banEntry) {
final @Nullable Date expiration = banEntry.getExpiration();
- final @Nullable String template = config.getString("ban-screen." + (expiration == null ? "permanent" : "temporary"));
+
+ final @Nullable String template = config.getString("ban-screen." + (expiration == null
+ ? "permanent"
+ : "temporary"
+ ));
+
if (template == null || template.isBlank() || template.equals("null"))
return Optional.empty();
- List placeholders = new ArrayList<>();
+ final List placeholders = new ArrayList<>();
+
placeholders.add(Placeholder.unparsed("reason", Optional.ofNullable(banEntry.getReason()).orElse("")));
+
if (expiration != null) {
- final @NotNull ZonedDateTime localExpiry = expiration.toInstant().atZone(ZoneOffset.systemDefault());
+ final ZonedDateTime localExpiry = expiration.toInstant().atZone(ZoneOffset.systemDefault());
+
placeholders.add(Formatter.date("expiration", localExpiry));
placeholders.add(Placeholder.component("expiration-relative", SMPCore.relativeTime(expiration)));
}
- return Optional.of(MiniMessage.miniMessage().deserialize(template, placeholders.toArray(TagResolver[]::new)));
+ return Optional.of(MiniMessage.miniMessage().deserialize(
+ template,
+ placeholders.toArray(TagResolver[]::new)
+ ));
}
// errors
public @NotNull Component errorNoPermission() {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.no-permission")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.no-permission"))
+ );
}
public @NotNull Component errorPlayerNotBanned(final @NotNull OfflinePlayer player) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.player-not-banned")), Placeholder.unparsed("player", Optional
- .ofNullable(player.getName()).orElse(player.getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.player-not-banned")),
+ Placeholder.unparsed("player", CachedProfile.getName(player))
+ );
}
public @NotNull Component errorNotMember(final @NotNull OfflinePlayer player) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.not-member")), Placeholder.unparsed("player", Optional
- .ofNullable(player.getName()).orElse(player.getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.not-member")),
+ Placeholder.unparsed("player", CachedProfile.getName(player))
+ );
}
public @NotNull Component errorNotMember() {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.not-member-you")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.not-member-you"))
+ );
}
- public @NotNull Component errorAltAlreadyMember(final @NotNull Member player) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.alt-already-member")), Placeholder.unparsed("player", Optional
- .ofNullable(player.player().getName()).orElse(player.player().getUniqueId().toString())));
+ public @NotNull Component errorAltAlreadyMember(final @NotNull Member member) {
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.alt-already-member")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component errorDisallowedCharacters(final @NotNull Set<@NotNull Character> chars) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.disallowed-characters")), Placeholder.unparsed("chars", chars.stream().map(String::valueOf).collect(Collectors.joining())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.disallowed-characters")),
+ Placeholder.unparsed("chars", chars.stream().map(String::valueOf).collect(Collectors.joining()))
+ );
}
- public @NotNull Component errorFailedDeleteMember(final @NotNull Member player) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.failed-delete-member")), Placeholder.unparsed("player", Optional
- .ofNullable(player.player().getName()).orElse(player.player().getUniqueId().toString())));
+ public @NotNull Component errorFailedDeleteMember(final @NotNull Member member) {
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.failed-delete-member")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component errorAlreadyYourAlt(final @NotNull Member alt) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.already-your-alt")), Placeholder.unparsed("alt", Optional
- .ofNullable(alt.player().getName()).orElse(alt.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.already-your-alt")),
+ Placeholder.unparsed("alt", CachedProfile.getName(alt.player()))
+ );
}
public @NotNull Component errorMaxAltsReached(final int max) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.max-alts-reached")), Placeholder.unparsed("max", String.valueOf(max)));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.max-alts-reached")),
+ Placeholder.unparsed("max", String.valueOf(max))
+ );
}
- public @NotNull Component errorMemberNotAlt(final @NotNull Member player) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.member-not-alt")), Placeholder.unparsed("player", Optional
- .ofNullable(player.player().getName()).orElse(player.player().getUniqueId().toString())));
+ public @NotNull Component errorMemberNotAlt(final @NotNull Member member) {
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.member-not-alt")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
- public @NotNull Component errorRemoveJoinedAlt(final @NotNull Member player) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.remove-joined-alt")), Placeholder.unparsed("player", Optional
- .ofNullable(player.player().getName()).orElse(player.player().getUniqueId().toString())));
+ public @NotNull Component errorRemoveJoinedAlt(final @NotNull Member member) {
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.remove-joined-alt")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component errorNeverJoined(final @NotNull OfflinePlayer player) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.never-joined")), Placeholder.unparsed("player", Optional
- .ofNullable(player.getName()).orElse(player.getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.never-joined")),
+ Placeholder.unparsed("player", CachedProfile.getName(player))
+ );
}
public @NotNull Component errorCommandOnStaff(final @NotNull String label) {
- return MiniMessage.miniMessage()
- .deserialize(Objects.requireNonNull(config.getString("error.command-on-staff")), Placeholder.unparsed("command", label));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.command-on-staff")),
+ Placeholder.unparsed("command", label)
+ );
}
public @NotNull Component errorNotCitizen() {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.not-citizen-you")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.not-citizen-you"))
+ );
}
public @NotNull Component errorNotCitizen(final @NotNull Member member) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.not-citizen")), Placeholder
- .unparsed("player", Optional
- .ofNullable(member.player().getName()).orElse(member.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.not-citizen")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component errorAlreadyCitizen() {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.already-citizen")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.already-citizen"))
+ );
}
public @NotNull Component errorAlreadyCitizen(final @NotNull Nation nation) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.already-citizen-nation")), Placeholder.unparsed("nation", nation.name));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.already-citizen-nation")),
+ Placeholder.unparsed("nation", nation.name)
+ );
}
public @NotNull Component errorAlreadyCitizen(final @NotNull Member member) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.already-citizen-player")), Placeholder.unparsed("player", Optional.ofNullable(member.player().getName()).orElse(member.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.already-citizen-player")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component errorOtherCitizen(final @NotNull Member member) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.other-citizen")), Placeholder.unparsed("player", Optional.ofNullable(member.player().getName()).orElse(member.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.other-citizen")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component errorKickLeadership() {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.kick-leadership")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.kick-leadership"))
+ );
}
public @NotNull Component errorLeaderLeave() {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.leader-leave")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.leader-leave"))
+ );
}
public @NotNull Component errorNationNotFound(final @NotNull String nation) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.nation-not-found")), Placeholder.unparsed("nation", nation));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.nation-not-found")),
+ Placeholder.unparsed("nation", nation)
+ );
}
public @NotNull Component errorNotInvited(final @NotNull Nation nation) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.not-invited")), Placeholder.unparsed("nation", nation.name));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.not-invited")),
+ Placeholder.unparsed("nation", nation.name)
+ );
}
public @NotNull Component errorAlreadyRequestedJoin(final @NotNull Nation nation) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.already-requested-join")), Placeholder.unparsed("nation", nation.name));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.already-requested-join")),
+ Placeholder.unparsed("nation", nation.name)
+ );
}
public @NotNull Component errorAlreadyInvited(final @NotNull Member member) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.already-invited")), Placeholder.unparsed("player", Optional.ofNullable(member.player().getName()).orElse(member.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.already-invited")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component errorNoRequest(final @NotNull Nation nation) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.no-request-nation")), Placeholder.unparsed("nation", nation.name));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.no-request-nation")),
+ Placeholder.unparsed("nation", nation.name)
+ );
}
public @NotNull Component errorNoRequest(final @NotNull Member member) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.no-request-player")), Placeholder.unparsed("player", Optional.ofNullable(member.player().getName()).orElse(member.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.no-request-player")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component errorViceConflict() {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.vice-conflict")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.vice-conflict"))
+ );
}
public @NotNull Component errorAlreadyVice(final @NotNull Member member) {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.already-vice")), Placeholder.unparsed("player", Optional.ofNullable(member.player().getName()).orElse(member.player().getUniqueId().toString())));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.already-vice")),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
+ );
}
public @NotNull Component errorDemoteLeader() {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.demote-leader")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.demote-leader"))
+ );
}
public @NotNull Component errorDemoteCitizen() {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.demote-citizen")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.demote-citizen"))
+ );
}
public @NotNull Component errorDurationZeroOrLess() {
- return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.duration-zero-or-less")));
+ return MiniMessage.miniMessage().deserialize(
+ Objects.requireNonNull(config.getString("error.duration-zero-or-less"))
+ );
}
public @NotNull Component errorInvalidDuration(final @NotNull String duration) {
@@ -703,16 +871,14 @@ public Messages() {
public @NotNull Component errorAlreadyMember(final @NotNull Member member) {
return MiniMessage.miniMessage().deserialize(
Objects.requireNonNull(config.getString("error.already-member")),
- Placeholder.unparsed("player", Optional.ofNullable(member.player().getName())
- .orElse(member.player().getUniqueId().toString()))
+ Placeholder.unparsed("player", CachedProfile.getName(member.player()))
);
}
public @NotNull Component errorAlreadyStaff(final @NotNull Member member) {
return MiniMessage.miniMessage().deserialize(
Objects.requireNonNull(config.getString("error.already-staff")),
- Placeholder.unparsed("player", Optional.ofNullable(member.player().getName())
- .orElse(member.player().getUniqueId().toString())),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player())),
Formatter.choice("staff", member.staff ? 1 : 0)
);
}
@@ -720,30 +886,35 @@ public Messages() {
public @NotNull Component errorRemoveMemberLeader(final @NotNull Member member, final @NotNull Nation nation) {
return MiniMessage.miniMessage().deserialize(
Objects.requireNonNull(config.getString("error.remove-member-leader")),
- Placeholder.unparsed("player", Optional.ofNullable(member.player().getName())
- .orElse(member.player().getUniqueId().toString())),
+ Placeholder.unparsed("player", CachedProfile.getName(member.player())),
Placeholder.unparsed("nation", nation.name)
);
}
public record SubCommandArgument(@NotNull String name, boolean required) {
public @NotNull Component component() {
- return required ? SMPCore.messages().subCommandArgumentRequired(name) : SMPCore.messages()
- .subCommandArgumentOptional(name);
+ return required
+ ? SMPCore.messages().subCommandArgumentRequired(name)
+ : SMPCore.messages().subCommandArgumentOptional(name);
}
public static @NotNull Component join(final @NotNull SubCommandArgument @NotNull [] args) {
- final @NotNull TextComponent.Builder builder = Component.text().append(Component.text(" "));
+ final TextComponent.Builder builder = Component.text().append(Component.text(" "));
for (int i = 0; i < args.length; ++i) {
builder.append(args[i].component());
- if (i < args.length - 1) builder.append(Component.text(" "));
+
+ if (i < args.length - 1)
+ builder.append(Component.text(" "));
}
+
return builder.build();
}
public static @NotNull SubCommandArgument @NotNull [] of(final @Nullable SubCommandArgument @NotNull ... args) {
- return Arrays.stream(args).filter(Objects::nonNull).toArray(SubCommandArgument[]::new);
+ return Arrays.stream(args)
+ .filter(Objects::nonNull)
+ .toArray(SubCommandArgument[]::new);
}
}
}
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/REST.java b/src/main/java/pro/cloudnode/smp/smpcore/REST.java
index 890c44c..61b023d 100644
--- a/src/main/java/pro/cloudnode/smp/smpcore/REST.java
+++ b/src/main/java/pro/cloudnode/smp/smpcore/REST.java
@@ -29,7 +29,7 @@ private void e404 (final @NotNull io.javalin.http.Context ctx) {
final @NotNull JsonObject obj = new JsonObject();
final @NotNull OfflinePlayer player = member.player();
obj.addProperty("uuid", member.uuid.toString());
- obj.addProperty("name", player.getName());
+ obj.addProperty("name", CachedProfile.getName(player));
obj.addProperty("nation", member.nationID);
obj.addProperty("staff", member.staff);
obj.addProperty("online", !member.staff && player.isOnline());
@@ -159,7 +159,7 @@ public REST(final int port) {
final @NotNull JsonObject altObj = new JsonObject();
final @NotNull OfflinePlayer player = alt.player();
altObj.addProperty("uuid", alt.uuid.toString());
- altObj.addProperty("name", player.getName());
+ altObj.addProperty("name", CachedProfile.getName(player));
altObj.addProperty("nation", alt.nationID);
altObj.addProperty("added", alt.added.getTime());
altObj.addProperty("lastSeen", alt.staff ? 0 : player.getLastSeen());
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/SMPCore.java b/src/main/java/pro/cloudnode/smp/smpcore/SMPCore.java
index e8ed2a2..a6fc47c 100644
--- a/src/main/java/pro/cloudnode/smp/smpcore/SMPCore.java
+++ b/src/main/java/pro/cloudnode/smp/smpcore/SMPCore.java
@@ -2,7 +2,9 @@
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
+import io.papermc.paper.util.Tick;
import net.kyori.adventure.text.Component;
+import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
@@ -16,8 +18,8 @@
import pro.cloudnode.smp.smpcore.command.SeenCommand;
import pro.cloudnode.smp.smpcore.command.TimeCommand;
import pro.cloudnode.smp.smpcore.command.UnbanCommand;
-import pro.cloudnode.smp.smpcore.listener.PlayerJoinListener;
import pro.cloudnode.smp.smpcore.listener.PlayerDeathListener;
+import pro.cloudnode.smp.smpcore.listener.PlayerJoinListener;
import pro.cloudnode.smp.smpcore.listener.PlayerPostRespawnListener;
import pro.cloudnode.smp.smpcore.listener.PlayerPreLoginListener;
import pro.cloudnode.smp.smpcore.listener.PlayerServerFullCheckListener;
@@ -92,6 +94,13 @@ public void onEnable() {
commands.put("alts", new AltsCommand(commands.get("smpcore")));
for (final Map.Entry entry : commands.entrySet())
Objects.requireNonNull(getServer().getPluginCommand(entry.getKey())).setExecutor(entry.getValue());
+
+ Bukkit.getScheduler().runTaskTimerAsynchronously(
+ this,
+ CachedProfile::cleanUp,
+ 0L,
+ Tick.tick().fromDuration(CachedProfile.STALE_WHILE_REVALIDATE)
+ );
}
@Override
@@ -235,4 +244,5 @@ public static boolean ifDisallowedCharacters(final @NotNull String source, final
public static @NotNull Date gameTime(final long ticks) {
return new Date(ticks * 3600 + 21600000);
}
+
}
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/command/BanCommand.java b/src/main/java/pro/cloudnode/smp/smpcore/command/BanCommand.java
index d71ede5..2e5fea3 100644
--- a/src/main/java/pro/cloudnode/smp/smpcore/command/BanCommand.java
+++ b/src/main/java/pro/cloudnode/smp/smpcore/command/BanCommand.java
@@ -5,6 +5,7 @@
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import pro.cloudnode.smp.smpcore.CachedProfile;
import pro.cloudnode.smp.smpcore.Member;
import pro.cloudnode.smp.smpcore.Permission;
import pro.cloudnode.smp.smpcore.SMPCore;
@@ -16,7 +17,6 @@
import java.util.Arrays;
import java.util.Date;
import java.util.List;
-import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@@ -102,7 +102,7 @@ public boolean run(@NotNull CommandSender sender, @NotNull String label, @NotNul
? String.join(" ", Arrays.copyOfRange(args, duration == null ? 1 : 2, args.length))
: null;
- final @NotNull OfflinePlayer target = SMPCore.getInstance().getServer().getOfflinePlayer(args[0]);
+ final @NotNull OfflinePlayer target = CachedProfile.get(args[0]);
final List banned = ban(
target,
@@ -121,10 +121,13 @@ public boolean run(@NotNull CommandSender sender, @NotNull String label, @NotNul
);
}
- @SuppressWarnings("NullableProblems")
@Override
public @NotNull List<@NotNull String> tab(@NotNull CommandSender sender, @NotNull String label, @NotNull String @NotNull [] args) {
- if (args.length <= 1) return Arrays.stream(SMPCore.getInstance().getServer().getOfflinePlayers()).filter(p -> !p.isBanned()).map(OfflinePlayer::getName).filter(Objects::nonNull).toList();
+ if (args.length <= 1)
+ return Arrays.stream(SMPCore.getInstance().getServer().getOfflinePlayers())
+ .filter(p -> !p.isBanned())
+ .map(CachedProfile::getName)
+ .toList();
return List.of();
}
}
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/command/MainCommand.java b/src/main/java/pro/cloudnode/smp/smpcore/command/MainCommand.java
index aceee3f..3d11912 100644
--- a/src/main/java/pro/cloudnode/smp/smpcore/command/MainCommand.java
+++ b/src/main/java/pro/cloudnode/smp/smpcore/command/MainCommand.java
@@ -11,6 +11,7 @@
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import pro.cloudnode.smp.smpcore.CachedProfile;
import pro.cloudnode.smp.smpcore.Member;
import pro.cloudnode.smp.smpcore.Messages;
import pro.cloudnode.smp.smpcore.Nation;
@@ -71,7 +72,8 @@ else switch (args[1]) {
if (sender instanceof final @NotNull Player player) {
final @NotNull Optional<@NotNull Member> member = Member.get(player);
member.ifPresent(value -> suggestions.addAll(value.getAlts().stream()
- .map(m -> m.player().getName()).filter(Objects::nonNull).toList()));
+ .map(m -> CachedProfile.getName(m.player()))
+ .toList()));
}
}
}
@@ -158,10 +160,11 @@ else switch (originalArgs[0]) {
final @NotNull OfflinePlayer target;
if (!(sender instanceof final @NotNull Player player)) {
if (originalArgs.length == 1) return sendMessage(sender, SMPCore.messages().usage(label, "list "));
- target = sender.getServer().getOfflinePlayer(originalArgs[1]);
+ target = CachedProfile.get(originalArgs[1]);
}
else {
- if (originalArgs.length > 1 && player.hasPermission(Permission.ALT_OTHER)) target = player.getServer().getOfflinePlayer(originalArgs[1]);
+ if (originalArgs.length > 1 && player.hasPermission(Permission.ALT_OTHER))
+ target = CachedProfile.get(originalArgs[1]);
else target = player;
}
final @NotNull Optional<@NotNull Member> targetMember = Member.get(target);
@@ -200,10 +203,11 @@ else switch (originalArgs[0]) {
final @NotNull OfflinePlayer target;
if (!(sender instanceof final @NotNull Player player)) {
if (args.length == 2) return sendMessage(sender, SMPCore.messages().usage(label, "add "));
- target = sender.getServer().getOfflinePlayer(args[2]);
+ target = CachedProfile.get(args[2]);
}
else {
- if (args.length > 2 && player.hasPermission(Permission.ALT_ADD_OTHER)) target = player.getServer().getOfflinePlayer(args[2]);
+ if (args.length > 2 && player.hasPermission(Permission.ALT_ADD_OTHER))
+ target = CachedProfile.get(args[2]);
else target = player;
}
final @NotNull Optional<@NotNull Member> tempTargetMember = Member.get(target);
@@ -220,7 +224,7 @@ else switch (originalArgs[0]) {
if (!sender.hasPermission(Permission.ALT_MAX_BYPASS) && targetMember.getAlts().size() >= SMPCore.config().altsMax())
return sendMessage(sender, SMPCore.messages().errorMaxAltsReached(SMPCore.config().altsMax()));
- final @NotNull OfflinePlayer altPlayer = sender.getServer().getOfflinePlayer(args[1]);
+ final @NotNull OfflinePlayer altPlayer = CachedProfile.get(args[1]);
final @NotNull Optional<@NotNull Member> altMember = Member.get(altPlayer);
if (altMember.isPresent()) {
if (altMember.get().isAlt() && Objects.requireNonNull(altMember.get().altOwnerUUID).equals(target.getUniqueId()))
@@ -245,7 +249,7 @@ else switch (originalArgs[0]) {
if (originalArgs.length == 1)
return sendMessage(sender, SMPCore.messages().usage(label, "remove "));
- final @NotNull OfflinePlayer altPlayer = sender.getServer().getOfflinePlayer(originalArgs[1]);
+ final @NotNull OfflinePlayer altPlayer = CachedProfile.get(originalArgs[1]);
final @NotNull Optional<@NotNull Member> altMember = Member.get(altPlayer);
if (altMember.isEmpty()) return sendMessage(sender, SMPCore.messages().errorNotMember(altPlayer));
@@ -306,7 +310,7 @@ public static boolean member(
if (args.length != 2)
return sendMessage(sender, SMPCore.messages().usage(label, "member add "));
- final OfflinePlayer target = sender.getServer().getOfflinePlayer(args[1]);
+ final OfflinePlayer target = CachedProfile.get(args[1]);
final Optional existing = Member.get(target);
if (existing.isPresent())
@@ -343,7 +347,7 @@ public static boolean member(
if (args.length != 2)
return sendMessage(sender, SMPCore.messages().usage(label, "member remove "));
- final OfflinePlayer target = sender.getServer().getOfflinePlayer(args[1]);
+ final OfflinePlayer target = CachedProfile.get(args[1]);
final Optional member = Member.get(target);
if (member.isEmpty())
@@ -362,7 +366,7 @@ public static boolean member(
if (args.length != 3)
return sendMessage(sender, SMPCore.messages().usage(label, "member staff " + (args.length > 1 ? args[1] : "") + " "));
- final OfflinePlayer target = sender.getServer().getOfflinePlayer(args[1]);
+ final OfflinePlayer target = CachedProfile.get(args[1]);
final boolean requestedStatus;
switch (args[2].toLowerCase()) {
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/command/NationCommand.java b/src/main/java/pro/cloudnode/smp/smpcore/command/NationCommand.java
index c19c817..20e033e 100644
--- a/src/main/java/pro/cloudnode/smp/smpcore/command/NationCommand.java
+++ b/src/main/java/pro/cloudnode/smp/smpcore/command/NationCommand.java
@@ -7,6 +7,7 @@
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import pro.cloudnode.smp.smpcore.CachedProfile;
import pro.cloudnode.smp.smpcore.CitizenRequest;
import pro.cloudnode.smp.smpcore.Member;
import pro.cloudnode.smp.smpcore.Messages;
@@ -20,7 +21,6 @@
import java.util.Collections;
import java.util.Date;
import java.util.List;
-import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
@@ -159,9 +159,10 @@ else switch (args[0]) {
if (!sender.hasPermission(Permission.NATION_CITIZENS_KICK))
break;
list.addAll(nation.get().citizens().stream()
- .filter(c -> !c.uuid.equals(nation.get().leaderUUID))
- .map(c -> c.player().getName())
- .filter(Objects::nonNull).toList());
+ .filter(c -> !c.uuid.equals(nation.get().leaderUUID))
+ .map(c -> CachedProfile.getName(c.player()))
+ .toList()
+ );
}
case "promote" -> {
if (other && !sender.hasPermission(Permission.NATION_PROMOTE_OTHER))
@@ -169,9 +170,10 @@ else switch (args[0]) {
if (!sender.hasPermission(Permission.NATION_PROMOTE))
break;
list.addAll(nation.get().citizens().stream()
- .filter(c -> !(c.uuid.equals(nation.get().leaderUUID) || c.uuid.equals(nation.get().viceLeaderUUID)))
- .map(c -> c.player().getName())
- .filter(Objects::nonNull).toList());
+ .filter(c -> !(c.uuid.equals(nation.get().leaderUUID) ||
+ c.uuid.equals(nation.get().viceLeaderUUID)))
+ .map(c -> CachedProfile.getName(c.player()))
+ .toList());
}
case "demote" -> {
if (other && !sender.hasPermission(Permission.NATION_DEMOTE_OTHER))
@@ -181,9 +183,8 @@ else switch (args[0]) {
final @NotNull Member vice = nation.get().vice();
if (vice.uuid.equals(nation.get().leaderUUID))
break;
- final var name = vice.player().getName();
- if (name != null)
- list.add(name);
+
+ list.add(CachedProfile.getName(vice.player()));
}
case "invite", "request", "req" -> {
if (other && !sender.hasPermission(Permission.NATION_INVITE_OTHER))
@@ -192,8 +193,8 @@ else switch (args[0]) {
break;
list.addAll(Member.get().stream()
.filter(m -> !nation.get().id.equals(m.nationID))
- .map(c -> c.player().getName())
- .filter(Objects::nonNull).toList());
+ .map(c -> CachedProfile.getName(c.player()))
+ .toList());
}
case "cancel", "reject", "decline", "withdraw", "refuse", "deny" -> {
if (other && !sender.hasPermission(Permission.NATION_INVITE_OTHER))
@@ -203,7 +204,9 @@ else switch (args[0]) {
list.addAll(Stream.concat(
CitizenRequest.get(nation.get(), true).stream(),
CitizenRequest.get(nation.get(), false).stream()
- ).map(req -> req.member().player().getName()).filter(Objects::nonNull).sorted().toList());
+ ).map(req -> CachedProfile.getName(req.member().player()))
+ .sorted()
+ .toList());
}
case "add" -> {
if (other && !sender.hasPermission(Permission.NATION_CITIZEN_ADD_OTHER))
@@ -211,9 +214,9 @@ else switch (args[0]) {
if (!sender.hasPermission(Permission.NATION_CITIZEN_ADD))
break;
list.addAll(Member.get().stream()
- .filter(m -> !nation.get().id.equals(m.nationID))
- .map(c -> c.player().getName())
- .filter(Objects::nonNull).toList());
+ .filter(m -> !nation.get().id.equals(m.nationID))
+ .map(c -> CachedProfile.getName(c.player()))
+ .toList());
}
}
}
@@ -433,7 +436,7 @@ public static boolean kickCitizen(
if (args.length == 0)
return sendMessage(sender, SMPCore.messages().usage(label, ""));
- final @NotNull OfflinePlayer target = sender.getServer().getOfflinePlayer(args[0]);
+ final @NotNull OfflinePlayer target = CachedProfile.get(args[0]);
final @NotNull Optional<@NotNull Member> targetMemberOptional = Member.get(target);
if (targetMemberOptional.isEmpty())
return sendMessage(sender, SMPCore.messages().errorNotMember(target));
@@ -464,7 +467,7 @@ public static boolean promoteCitizen(
if (args.length == 0)
return sendMessage(sender, SMPCore.messages().usage(label, ""));
- final @NotNull OfflinePlayer target = sender.getServer().getOfflinePlayer(args[0]);
+ final @NotNull OfflinePlayer target = CachedProfile.get(args[0]);
final @NotNull Optional<@NotNull Member> targetMember = Member.get(target);
if (targetMember.isEmpty())
return sendMessage(sender, SMPCore.messages().errorNotMember(target));
@@ -509,7 +512,7 @@ public static boolean demoteViceLeader(
if (args.length == 0)
return sendMessage(sender, SMPCore.messages().usage(label, ""));
- final @NotNull OfflinePlayer target = sender.getServer().getOfflinePlayer(args[0]);
+ final @NotNull OfflinePlayer target = CachedProfile.get(args[0]);
final @NotNull Optional<@NotNull Member> targetMemberOptional = Member.get(target);
if (targetMemberOptional.isEmpty())
return sendMessage(sender, SMPCore.messages().errorNotMember(target));
@@ -552,7 +555,7 @@ public static boolean inviteCitizen(
if (args.length < 1)
return sendMessage(sender, SMPCore.messages().usage(label, ""));
- final var targetPlayer = sender.getServer().getOfflinePlayer(args[0]);
+ final var targetPlayer = CachedProfile.get(args[0]);
final @NotNull var target = Member.get(targetPlayer);
if (target.isEmpty())
@@ -604,7 +607,7 @@ public static boolean addCitizen(
if (args.length < 1)
return sendMessage(sender, SMPCore.messages().usage(label, ""));
- final @NotNull var targetPlayer = sender.getServer().getOfflinePlayer(args[0]);
+ final @NotNull var targetPlayer = CachedProfile.get(args[0]);
final @NotNull var target = Member.get(targetPlayer);
if (target.isEmpty())
@@ -737,7 +740,7 @@ public static boolean nationCancel(
if (args.length < 1)
return sendMessage(sender, SMPCore.messages().usage(label, ""));
- final var targetPlayer = sender.getServer().getOfflinePlayer(args[0]);
+ final var targetPlayer = CachedProfile.get(args[0]);
final @NotNull var target = Member.get(targetPlayer);
if (target.isEmpty())
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/command/SeenCommand.java b/src/main/java/pro/cloudnode/smp/smpcore/command/SeenCommand.java
index b7b0957..a20a045 100644
--- a/src/main/java/pro/cloudnode/smp/smpcore/command/SeenCommand.java
+++ b/src/main/java/pro/cloudnode/smp/smpcore/command/SeenCommand.java
@@ -3,12 +3,12 @@
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
+import pro.cloudnode.smp.smpcore.CachedProfile;
import pro.cloudnode.smp.smpcore.Member;
import pro.cloudnode.smp.smpcore.Permission;
import pro.cloudnode.smp.smpcore.SMPCore;
import java.util.List;
-import java.util.Objects;
import java.util.Optional;
public final class SeenCommand extends Command {
@@ -19,7 +19,7 @@ public boolean run(@NotNull CommandSender sender, @NotNull String label, @NotNul
if (args.length != 1) return sendMessage(sender, SMPCore.messages().usage(label, ""));
- final @NotNull OfflinePlayer player = sender.getServer().getOfflinePlayer(args[0]);
+ final @NotNull OfflinePlayer player = CachedProfile.get(args[0]);
if (!player.hasPlayedBefore()) return sendMessage(sender, SMPCore.messages().errorNeverJoined(player));
@@ -31,10 +31,12 @@ public boolean run(@NotNull CommandSender sender, @NotNull String label, @NotNul
.orElseGet(() -> sendMessage(sender, SMPCore.messages().seen(player)));
}
- @SuppressWarnings("NullableProblems")
@Override
public @NotNull List<@NotNull String> tab(@NotNull CommandSender sender, @NotNull String label, @NotNull String @NotNull [] args) {
if (sender.hasPermission(Permission.SEEN_STAFF)) return Member.getNames().stream().toList();
- else return Member.get().stream().filter(m -> !m.staff).map(m -> m.player().getName()).filter(Objects::nonNull).toList();
+ else return Member.get().stream()
+ .filter(m -> !m.staff)
+ .map(m -> CachedProfile.getName(m.player()))
+ .toList();
}
}
diff --git a/src/main/java/pro/cloudnode/smp/smpcore/command/UnbanCommand.java b/src/main/java/pro/cloudnode/smp/smpcore/command/UnbanCommand.java
index 9bbc375..bfa2953 100644
--- a/src/main/java/pro/cloudnode/smp/smpcore/command/UnbanCommand.java
+++ b/src/main/java/pro/cloudnode/smp/smpcore/command/UnbanCommand.java
@@ -6,6 +6,7 @@
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
+import pro.cloudnode.smp.smpcore.CachedProfile;
import pro.cloudnode.smp.smpcore.Member;
import pro.cloudnode.smp.smpcore.Permission;
import pro.cloudnode.smp.smpcore.SMPCore;
@@ -23,7 +24,7 @@ public final class UnbanCommand extends Command {
public boolean run(@NotNull CommandSender sender, @NotNull String label, @NotNull String @NotNull [] args) {
if (!sender.hasPermission(Permission.BAN)) return sendMessage(sender, SMPCore.messages().errorNoPermission());
if (args.length < 1) return sendMessage(sender, SMPCore.messages().usage(label, ""));
- final @NotNull OfflinePlayer target = SMPCore.getInstance().getServer().getOfflinePlayer(args[0]);
+ final @NotNull OfflinePlayer target = CachedProfile.get(args[0]);
final @NotNull Optional<@NotNull Member> targetMember = Member.get(target);
if (targetMember.isEmpty()) {
if (!target.isBanned()) return sendMessage(sender, SMPCore.messages().errorPlayerNotBanned(target));
diff --git a/src/main/resources/init.sql b/src/main/resources/init.sql
index 1ef0f56..4333a34 100644
--- a/src/main/resources/init.sql
+++ b/src/main/resources/init.sql
@@ -1,37 +1,52 @@
-CREATE TABLE IF NOT EXISTS `members` (
- `uuid` CHAR(36) PRIMARY KEY NOT NULL COLLATE NOCASE,
- `nation` CHAR(2) DEFAULT NULL COLLATE NOCASE,
- `staff` TINYINT(1) NOT NULL DEFAULT 0,
- `alt_owner` CHAR(36) DEFAULT NULL COLLATE NOCASE,
- `added` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
+CREATE TABLE IF NOT EXISTS `members`
+(
+ `uuid` CHAR(36) PRIMARY KEY NOT NULL COLLATE NOCASE,
+ `nation` CHAR(2) DEFAULT NULL COLLATE NOCASE,
+ `staff` TINYINT(1) NOT NULL DEFAULT 0,
+ `alt_owner` CHAR(36) DEFAULT NULL COLLATE NOCASE,
+ `added` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-CREATE TABLE IF NOT EXISTS `tokens` (
- `token` CHAR(36) PRIMARY KEY NOT NULL COLLATE NOCASE,
- `member` CHAR(36) NOT NULL COLLATE NOCASE,
- `created` CHAR(36) NOT NULL COLLATE NOCASE,
- `last_used` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
+CREATE TABLE IF NOT EXISTS `tokens`
+(
+ `token` CHAR(36) PRIMARY KEY NOT NULL COLLATE NOCASE,
+ `member` CHAR(36) NOT NULL COLLATE NOCASE,
+ `created` CHAR(36) NOT NULL COLLATE NOCASE,
+ `last_used` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-CREATE TABLE IF NOT EXISTS `nations` (
- `id` CHAR(2) PRIMARY KEY NOT NULL COLLATE NOCASE,
- `name` VARCHAR(128) NOT NULL COLLATE NOCASE,
- `short_name` VARCHAR(16) NOT NULL COLLATE NOCASE,
- `color` CHAR(6) NOT NULL COLLATE NOCASE,
- `leader` CHAR(36) NOT NULL COLLATE NOCASE,
- `vice` CHAR(36) NOT NULL COLLATE NOCASE,
- `founded` DATETIME NOT NULL,
- `founded_ticks` INTEGER NOT NULL,
- `bank` CHAR(16) NOT NULL COLLATE BINARY
+CREATE TABLE IF NOT EXISTS `nations`
+(
+ `id` CHAR(2) PRIMARY KEY NOT NULL COLLATE NOCASE,
+ `name` VARCHAR(128) NOT NULL COLLATE NOCASE,
+ `short_name` VARCHAR(16) NOT NULL COLLATE NOCASE,
+ `color` CHAR(6) NOT NULL COLLATE NOCASE,
+ `leader` CHAR(36) NOT NULL COLLATE NOCASE,
+ `vice` CHAR(36) NOT NULL COLLATE NOCASE,
+ `founded` DATETIME NOT NULL,
+ `founded_ticks` INTEGER NOT NULL,
+ `bank` CHAR(16) NOT NULL COLLATE BINARY
);
-CREATE TABLE IF NOT EXISTS `citizen_requests` (
- `member` CHAR(36) NOT NULL COLLATE NOCASE,
- `nation` CHAR(2) NOT NULL COLLATE NOCASE,
- `mode` TINYINT(1) NOT NULL, -- 0 = nation invites, 1 = member requests
- `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `expires` DATETIME NOT NULL,
+CREATE TABLE IF NOT EXISTS `citizen_requests`
+(
+ `member` CHAR(36) NOT NULL COLLATE NOCASE,
+ `nation` CHAR(2) NOT NULL COLLATE NOCASE,
+ `mode` TINYINT(1) NOT NULL, -- 0 = nation invites, 1 = member requests
+ `created` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `expires` DATETIME NOT NULL,
PRIMARY KEY (`member`, `nation`)
);
-DELETE from `citizen_requests` WHERE `expires` >= CURRENT_TIMESTAMP;
+DELETE
+from `citizen_requests`
+WHERE `expires` >= CURRENT_TIMESTAMP;
+
+CREATE TABLE IF NOT EXISTS `cached_profiles`
+(
+ `uuid` CHAR(36) NOT NULL COLLATE NOCASE,
+ `name` VARCHAR(16) NOT NULL COLLATE NOCASE,
+ `fetched` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (`uuid`),
+ UNIQUE (`name`)
+);