Skip to content

Commit

Permalink
Command to check when player was last online (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
zefir-git authored May 19, 2024
2 parents 2a6f798 + 9386103 commit 61278a5
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/main/java/pro/cloudnode/smp/smpcore/Configuration.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
package pro.cloudnode.smp.smpcore;

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Formatter;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.jetbrains.annotations.NotNull;

import java.time.temporal.ChronoUnit;
import java.util.Objects;

public final class Configuration extends BaseConfig {
public Configuration() {
super("config.yml");
Expand All @@ -25,4 +34,30 @@ public int membersInactiveDays() {
public int altsMax() {
return config.getInt("alts.max");
}

public @NotNull Component relativeTime(final int t, final @NotNull ChronoUnit unit) {
final @NotNull String formatString = Objects.requireNonNull(config.getString("relative-time." + switch (unit) {
case SECONDS -> "seconds";
case MINUTES -> "minutes";
case HOURS -> "hours";
case DAYS -> "days";
case MONTHS -> "months";
case YEARS -> "years";
default -> {
throw new IllegalStateException("No relative time format for ChronoUnit " + unit);
}
}));
return MiniMessage.miniMessage()
.deserialize(formatString, Formatter.number("t", t), Formatter.choice("format", Math.abs(t)));
}

public @NotNull Component relativeTimeFuture(final @NotNull Component relativeTime) {
return MiniMessage.miniMessage()
.deserialize(Objects.requireNonNull(config.getString("relative-time.future")), Placeholder.component("t", relativeTime));
}

public @NotNull Component relativeTimePast(final @NotNull Component relativeTime) {
return MiniMessage.miniMessage()
.deserialize(Objects.requireNonNull(config.getString("relative-time.past")), Placeholder.component("t", relativeTime));
}
}
35 changes: 35 additions & 0 deletions src/main/java/pro/cloudnode/smp/smpcore/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Formatter;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -141,6 +144,32 @@ public Messages() {
.ofNullable(alt.player().getName()).orElse(alt.player().getUniqueId().toString())));
}

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)));
}

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)));
}

// errors

public @NotNull Component errorNoPermission() {
Expand Down Expand Up @@ -204,6 +233,12 @@ public Messages() {
.ofNullable(player.player().getName()).orElse(player.player().getUniqueId().toString())));
}

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())));
}

public record SubCommandArgument(@NotNull String name, boolean required) {
public @NotNull Component component() {
return required ? SMPCore.messages().subCommandArgumentRequired(name) : SMPCore.messages()
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/pro/cloudnode/smp/smpcore/Permission.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ public final class Permission {
* Remove an alt that has joined the server
*/
public static @NotNull String ALT_REMOVE_JOINED = "smpcore.alt.remove.joined";

public static @NotNull String SEEN = "smpcore.seen";
}
30 changes: 30 additions & 0 deletions src/main/java/pro/cloudnode/smp/smpcore/SMPCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import net.kyori.adventure.text.Component;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import pro.cloudnode.smp.smpcore.command.AltsCommand;
import pro.cloudnode.smp.smpcore.command.BanCommand;
import pro.cloudnode.smp.smpcore.command.Command;
import pro.cloudnode.smp.smpcore.command.MainCommand;
import pro.cloudnode.smp.smpcore.command.SeenCommand;
import pro.cloudnode.smp.smpcore.command.UnbanCommand;
import pro.cloudnode.smp.smpcore.listener.NationTeamUpdaterListener;

Expand All @@ -17,6 +19,8 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
Expand Down Expand Up @@ -68,6 +72,7 @@ public void onEnable() {
put("smpcore", new MainCommand());
put("ban", new BanCommand());
put("unban", new UnbanCommand());
put("seen", new SeenCommand());
}};
commands.put("alts", new AltsCommand(commands.get("smpcore")));
for (final @NotNull Map.Entry<@NotNull String, @NotNull Command> entry : commands.entrySet())
Expand Down Expand Up @@ -162,4 +167,29 @@ public static boolean ifDisallowedCharacters(final @NotNull String source, final
}
return false;
}

public static @NotNull Component relativeTime(final @NotNull Date date1, final @NotNull Date date2) {
final long diff = date1.getTime() - date2.getTime();
final long abs = Math.abs(diff);
final double seconds = Math.floor(abs / 1000.0);
final double minutes = Math.floor(seconds / 60.0);
final double hours = Math.floor(minutes / 60.0);
final double days = Math.floor(hours / 24.0);
final double months = Math.floor(days / 30.0);
final double years = Math.floor(months / 12.0);

final @NotNull Component t;
if (years > 0) t = SMPCore.config().relativeTime((int) years, ChronoUnit.YEARS);
else if (months > 0) t = SMPCore.config().relativeTime((int) months, ChronoUnit.MONTHS);
else if (days > 0) t = SMPCore.config().relativeTime((int) days, ChronoUnit.DAYS);
else if (hours > 0) t = SMPCore.config().relativeTime((int) hours, ChronoUnit.HOURS);
else if (minutes > 0) t = SMPCore.config().relativeTime((int) minutes, ChronoUnit.MINUTES);
else t = SMPCore.config().relativeTime((int) seconds, ChronoUnit.SECONDS);

return diff < 0 ? SMPCore.config().relativeTimePast(t) : SMPCore.config().relativeTimeFuture(t);
}

public static @NotNull Component relativeTime(final @NotNull Date date) {
return relativeTime(date, new Date());
}
}
34 changes: 34 additions & 0 deletions src/main/java/pro/cloudnode/smp/smpcore/command/SeenCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package pro.cloudnode.smp.smpcore.command;

import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
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.Optional;

public final class SeenCommand extends Command {

@Override
public boolean run(@NotNull CommandSender sender, @NotNull String label, @NotNull String @NotNull [] args) {
if (!sender.hasPermission(Permission.SEEN)) return sendMessage(sender, SMPCore.messages().errorNoPermission());

if (args.length != 1) return sendMessage(sender, SMPCore.messages().usage(label, "<player>"));

final @NotNull OfflinePlayer player = sender.getServer().getOfflinePlayer(args[0]);

if (!player.hasPlayedBefore()) return sendMessage(sender, SMPCore.messages().errorNeverJoined(player));

final @NotNull Optional<@NotNull Member> member = Member.get(player.getUniqueId());
return member.map(m -> sendMessage(sender, SMPCore.messages().seen(m)))
.orElseGet(() -> sendMessage(sender, SMPCore.messages().seen(player)));
}

@Override
public @NotNull List<@NotNull String> tab(@NotNull CommandSender sender, @NotNull String label, @NotNull String @NotNull [] args) {
return Member.getNames().stream().toList();
}
}
10 changes: 10 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,13 @@ members:
alts:
# Maximum number of alts you can have
max: 10

relative-time:
seconds: <t> <format:'0#seconds|1#second|1<seconds'>
minutes: <t> <format:'0#minutes|1#minute|1<minutes'>
hours: <t> <format:'0#hours|1#hour|1<hours'>
days: <t> <format:'0#days|1#day|1<days'>
months: <t> <format:'0#months|1#month|1<months'>
years: <t> <format:'0#years|1#year|1<years'>
future: in <t>
past: <t> ago
7 changes: 7 additions & 0 deletions src/main/resources/messages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ alts:
created: <green>(!) Created member profile for <gray><alt></gray> and added as an alt.</green>
deleted: <green>(!) Deleted alt member profile for <gray><alt></gray>.</green>

seen:
online: <green>(!) Player <gray><player></gray> is online.</green>
active: <aqua>(!) Member <white><player></white> is <green>active</green> and last seen on <white><last-seen:'dd MMM yyyy HH:mm'> UTC</white> <gray>(<last-seen-relative>)</aqua>
inactive: <aqua>(!) Member <white><player></white> is <red>inactive</red> and last seen on <white><last-seen:'dd MMM yyyy HH:mm'> UTC</white> <gray>(<last-seen-relative>)</aqua>
non-member: <aqua>(!) Player <white><player></white> was last seen on <white><last-seen:'dd MMM yyyy HH:mm'> UTC</white> <gray>(<last-seen-relative>)</aqua>

error:
no-permission: <red>(!) You don't have permission to use this command.</red>
player-not-banned: <red>(!) Player <gray><player></gray> is not banned and is not a member.</red>
Expand All @@ -45,3 +51,4 @@ error:
max-alts-reached: <red>(!) You cannot have more than <gray><max></gray> alts.</red>
member-not-alt: <red>(!) Member <gray><player></gray> is not an alt.</red>
remove-joined-alt: <red>(!) You cannot remove alt player <gray><alt></gray> because they have played the server.</red>
never-joined: <red>(!) Player <gray><player></gray> has never played on the server.</red>
5 changes: 5 additions & 0 deletions src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,8 @@ commands:
description: Manage alternate accounts
usage: /<command>
aliases: [ alt ]
seen:
permission: smpcore.seen
description: Check when a player was last online
usage: /<command> <player>
aliases: [ lastseen ]

0 comments on commit 61278a5

Please sign in to comment.