Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manage nation members #27

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions src/main/java/pro/cloudnode/smp/smpcore/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
import net.kyori.adventure.text.minimessage.tag.resolver.Formatter;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.OfflinePlayer;
import org.bukkit.permissions.Permissible;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
Expand Down Expand Up @@ -182,6 +184,122 @@ public Messages() {
.toLocalDateTime()), Placeholder.unparsed("day", String.valueOf(day)), Placeholder.unparsed("day", String.valueOf(day)), Formatter.choice("day-format", day));
}

public @NotNull Component nationMembersStatus(final @NotNull Member member) {
return MiniMessage.miniMessage()
.deserialize(Objects.requireNonNull(config.getString(member.isActive() ? "nation.members.status.active" : "nation.members.status.inactive")));
}

public @NotNull Component nationMembersList(final @NotNull Nation nation, final @NotNull Permissible sender) {
final @NotNull HashSet<@NotNull Member> members = nation.members();
final @NotNull Component header = MiniMessage.miniMessage()
.deserialize(Objects.requireNonNull(config.getString("nation.members.list.header"))
.replaceAll("<color>", "<#" + nation.color + ">")
.replaceAll("</color>", "</#" + 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() + "")
);

final @NotNull List<@NotNull Component> list = new ArrayList<>();

final @NotNull Member leader = members.stream().filter(m -> m.uuid.equals(nation.leaderUUID)).findFirst().orElseThrow(IllegalStateException::new);
list.add(nationMembersListEntry(nation, leader, sender));

final @NotNull Member vice = members.stream().filter(m -> m.uuid.equals(nation.viceLeaderUUID)).findFirst().orElseThrow(IllegalStateException::new);
if (!vice.uuid.equals(leader.uuid))
list.add(nationMembersListEntry(nation, vice, sender));

final @NotNull List<@NotNull Component> citizens = members.stream().filter(m -> !m.uuid.equals(leader.uuid) && !m.uuid.equals(vice.uuid) && m.isActive()).map(m -> nationMembersListEntry(nation, m, sender)).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 -> nationMembersListEntry(nation, m, sender)).toList();
list.addAll(inactive);

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

return Component.text().append(header).append(Component.newline()).append(listComponent.build()).build();
}

private @NotNull Component nationMembersListEntry(final @NotNull Nation nation, final @NotNull Member member, final @NotNull Permissible sender) {
if (member.uuid.equals(nation.leaderUUID)) {
return MiniMessage.miniMessage()
.deserialize(Objects.requireNonNull(config.getString("nation.members.list.entry.leader"))
.replaceAll("<color>", "<#" + nation.color + ">")
.replaceAll("</color>", "</#" + nation.color + ">")
.replaceAll("<member-name>", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())),
Placeholder.component("member-status", nationMembersStatus(member)),
Placeholder.component("buttons", nationMembersListButtons(nation, member, sender))
);
}
if (member.uuid.equals(nation.viceLeaderUUID)) {
return MiniMessage.miniMessage()
.deserialize(Objects.requireNonNull(config.getString("nation.members.list.entry.vice"))
.replaceAll("<color>", "<#" + nation.color + ">")
.replaceAll("</color>", "</#" + nation.color + ">")
.replaceAll("<member-name>", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())),
Placeholder.component("member-status", nationMembersStatus(member)),
Placeholder.component("buttons", nationMembersListButtons(nation, member, sender))
);
}
if (member.isActive()) {
return MiniMessage.miniMessage()
.deserialize(Objects.requireNonNull(config.getString("nation.members.list.entry.citizen"))
.replaceAll("<color>", "<#" + nation.color + ">")
.replaceAll("</color>", "</#" + nation.color + ">")
.replaceAll("<member-name>", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())),
Placeholder.component("member-status", nationMembersStatus(member)),
Placeholder.component("buttons", nationMembersListButtons(nation, member, sender))
);
}
return MiniMessage.miniMessage()
.deserialize(Objects.requireNonNull(config.getString("nation.members.list.entry.inactive-citizen"))
.replaceAll("<color>", "<#" + nation.color + ">")
.replaceAll("</color>", "</#" + nation.color + ">")
.replaceAll("<member-name>", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())),
Placeholder.component("member-status", nationMembersStatus(member)),
Placeholder.component("buttons", nationMembersListButtons(nation, member, sender))
);
}

private @NotNull Component nationMembersListButtons(final @NotNull Nation nation, final @NotNull Member member, final @NotNull Permissible sender) {
final @NotNull List<@NotNull Component> buttons = new ArrayList<>();
if (sender.hasPermission(Permission.NATION_MEMBERS_KICK) && !(member.uuid.equals(nation.leaderUUID) || member.uuid.equals(nation.viceLeaderUUID)))
buttons.add(nationMembersListButton("kick", nation, member));
if (sender.hasPermission(Permission.NATION_VICE_DEMOTE) && member.uuid.equals(nation.viceLeaderUUID) && !member.uuid.equals(nation.leaderUUID))
buttons.add(nationMembersListButton("demote", nation, member));
if (sender.hasPermission(Permission.NATION_VICE_PROMOTE) && nation.viceLeaderUUID.equals(nation.leaderUUID) && !(member.uuid.equals(nation.leaderUUID) || member.uuid.equals(nation.viceLeaderUUID)) && member.isActive())
buttons.add(nationMembersListButton("promote", nation, member));

final @NotNull TextComponent.Builder buttonsComponent = Component.text();
if (!buttons.isEmpty()) buttonsComponent.append(MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("nation.members.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.members.list.buttons.separator"))));
}
if (!buttons.isEmpty()) buttonsComponent.append(MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("nation.members.list.buttons.suffix"))));

return Component.text().append(buttonsComponent.build()).build();
}

private @NotNull Component nationMembersListButton(final @NotNull String button, final @NotNull Nation nation, final @NotNull Member member) {
return MiniMessage.miniMessage()
.deserialize(Objects.requireNonNull(config.getString("nation.members.list.buttons." + button))
.replaceAll("<color>", "<#" + nation.color + ">")
.replaceAll("</color>", "</#" + nation.color + ">")
.replaceAll("<member-name>", Optional.ofNullable(member.player().getName()).orElse(member.uuid.toString())));
}

public @NotNull Component nationMembersKicked(final @NotNull Member member) {
return MiniMessage.miniMessage()
.deserialize(Objects.requireNonNull(config.getString("nation.members.kicked")), Placeholder.unparsed("player", Optional
.ofNullable(member.player().getName()).orElse(member.uuid.toString())));
}

// errors

public @NotNull Component errorNoPermission() {
Expand Down Expand Up @@ -256,6 +374,24 @@ public Messages() {
.deserialize(Objects.requireNonNull(config.getString("error.command-on-staff")), Placeholder.unparsed("command", label));
}

public @NotNull Component errorNotInNation() {
return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.not-in-nation")));
}

public @NotNull Component errorMemberNotYourNation(final @NotNull Member member) {
return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.member-not-your-nation")), Placeholder
.unparsed("player", Optional
.ofNullable(member.player().getName()).orElse(member.player().getUniqueId().toString())));
}

public @NotNull Component errorNotPlayer() {
return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.not-player")));
}

public @NotNull Component errorKickLeadership() {
return MiniMessage.miniMessage().deserialize(Objects.requireNonNull(config.getString("error.kick-leadership")));
}

public record SubCommandArgument(@NotNull String name, boolean required) {
public @NotNull Component component() {
return required ? SMPCore.messages().subCommandArgumentRequired(name) : SMPCore.messages()
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/pro/cloudnode/smp/smpcore/Nation.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ public void add(final @NotNull Member member) {
getTeam().addPlayer(member.player());
}

public void remove(final @NotNull Member member) {
member.nationID = null;
member.save();
getTeam().removePlayer(member.player());
}

public Nation(final @NotNull ResultSet rs) throws @NotNull SQLException {
this(
rs.getString("id"),
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/pro/cloudnode/smp/smpcore/Permission.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,29 @@ public final class Permission {
* Allow seeing the game time and date
*/
public static @NotNull String TIME = "smpcore.time";

/**
* Access to the {@code /nation} command
*/
public static @NotNull String NATION = "smpcore.nation";

/**
* List the members of your nation
*/
public static @NotNull String NATION_MEMBERS_LIST = "smpcore.nation.members.list";

/**
* Kick nation members
*/
public static @NotNull String NATION_MEMBERS_KICK = "smpcore.nation.members.kick";

/**
* Appoint nation citizen as vice-leader
*/
public static @NotNull String NATION_VICE_PROMOTE = "smpcore.nation.vice-promote";

/**
* Relieve vice-leader of duties
*/
public static @NotNull String NATION_VICE_DEMOTE = "smpcore.nation.vice-demote";
}
2 changes: 2 additions & 0 deletions src/main/java/pro/cloudnode/smp/smpcore/SMPCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
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.NationCommand;
import pro.cloudnode.smp.smpcore.command.SeenCommand;
import pro.cloudnode.smp.smpcore.command.TimeCommand;
import pro.cloudnode.smp.smpcore.command.UnbanCommand;
Expand Down Expand Up @@ -78,6 +79,7 @@ public void onEnable() {
put("unban", new UnbanCommand());
put("seen", new SeenCommand());
put("time", new TimeCommand());
put("nation", new NationCommand());
}};
commands.put("alts", new AltsCommand(commands.get("smpcore")));
for (final @NotNull Map.Entry<@NotNull String, @NotNull Command> entry : commands.entrySet())
Expand Down
14 changes: 9 additions & 5 deletions src/main/java/pro/cloudnode/smp/smpcore/command/MainCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public boolean run(@NotNull CommandSender sender, @NotNull String label, @NotNul
return switch (args[0]) {
case "reload" -> reload(sender);
case "alt" -> alt(sender, argsSubset, label + " " + args[0]);
case "time", "date" -> time(sender, argsSubset, label + " " + args[0]);
case "time", "date" -> time(sender);
default -> sendMessage(sender, MiniMessage.miniMessage()
.deserialize("<red>(!) Unrecognised command <gray><command>", Placeholder.unparsed("command", args[0])));
};
Expand Down Expand Up @@ -98,9 +98,9 @@ public static boolean reload(final @NotNull CommandSender sender) {
}

/**
* <li>{@code alt} - show list of subcommands
* <li>{@code alt list [player]} - show list of alts
* <li>{@code alt add <username> [player]} - add an alt
* <li>{@code /command alt} - show list of subcommands
* <li>{@code /command alt list [player]} - show list of alts
* <li>{@code /command alt add <username> [player]} - add an alt
*/
public static boolean alt(final @NotNull CommandSender sender, final @NotNull String @NotNull [] originalArgs, final @NotNull String label) {
if (!sender.hasPermission(Permission.ALT)) return sendMessage(sender, SMPCore.messages().errorNoPermission());
Expand Down Expand Up @@ -237,7 +237,11 @@ else switch (originalArgs[0]) {
}
}

public static boolean time(final @NotNull CommandSender sender, final @NotNull String @NotNull [] args, final @NotNull String label) {

/**
* Usage: {@code /<command> time}
*/
public static boolean time(final @NotNull CommandSender sender) {
if (!sender.hasPermission(Permission.TIME))
return sendMessage(sender, SMPCore.messages().errorNoPermission());
return sendMessage(sender, SMPCore.messages().time(SMPCore.gameTime()));
Expand Down
Loading
Loading