diff --git a/src/main/java/me/trouper/trimalias/server/Manager.java b/src/main/java/me/trouper/trimalias/server/Manager.java index 0986959..74d7fe3 100755 --- a/src/main/java/me/trouper/trimalias/server/Manager.java +++ b/src/main/java/me/trouper/trimalias/server/Manager.java @@ -2,7 +2,9 @@ package me.trouper.trimalias.server; import me.trouper.trimalias.data.IO; import me.trouper.trimalias.server.commands.*; +import me.trouper.trimalias.server.events.ConnectEvent; import me.trouper.trimalias.server.events.JoinEvent; +import me.trouper.trimalias.server.events.RegistryListeners; import me.trouper.trimalias.server.systems.PollingBackend; import me.trouper.trimalias.utils.visual.BlockDisplayRaytracer; import net.luckperms.api.LuckPerms; @@ -43,9 +45,12 @@ public class Manager { new SeasonCommand().register(); new SpawnCommand().register(); new CopyInvCommand().register(); + new BroadcastDonationCommand().register(); } private void registerEvents() { + new RegistryListeners().registerEvents(); new JoinEvent().registerEvents(); + new ConnectEvent().registerEvents(); } } \ No newline at end of file diff --git a/src/main/java/me/trouper/trimalias/server/commands/BroadcastDonationCommand.java b/src/main/java/me/trouper/trimalias/server/commands/BroadcastDonationCommand.java new file mode 100644 index 0000000..0998e37 --- /dev/null +++ b/src/main/java/me/trouper/trimalias/server/commands/BroadcastDonationCommand.java @@ -0,0 +1,53 @@ +package me.trouper.trimalias.server.commands; + +import me.trouper.trimalias.utils.Text; +import me.trouper.trimalias.utils.command.Args; +import me.trouper.trimalias.utils.command.CommandRegistry; +import me.trouper.trimalias.utils.command.Permission; +import me.trouper.trimalias.utils.command.QuickCommand; +import me.trouper.trimalias.utils.command.completions.CompletionBuilder; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import java.util.List; + +@CommandRegistry(value = "broadcastdonation", permission = @Permission("trimalias .broadcast")) +public class BroadcastDonationCommand implements QuickCommand { + @Override + public void dispatchCommand(CommandSender sender, Command command, String label, Args args) { + String name = args.get(0).toString(); + String amount = args.get(1).toString(); + String price = args.get(2).toString(); + String item = args.getAll(3).toString(); + OfflinePlayer p = Bukkit.getOfflinePlayer(name); + List imageLines = Text.imageToList("https://crafatar.com/avatars/" + p.getUniqueId() + "?size=8&overlay"); + imageLines.set(0,imageLines.get(0) + " §8§m=========================="); + imageLines.set(2,imageLines.get(2) + " §b§k... §7Store Purchase §b§k..."); + imageLines.set(3,imageLines.get(3) + " §7GG, §b§n" + name + "§7 has bought"); + imageLines.set(4,imageLines.get(4) + " §7" + amount + "x " + LegacyComponentSerializer.legacySection().serialize(Text.color(item)) + "§7 for §2$" + price); + imageLines.set(5,imageLines.get(5) + " §7Thank you!"); + imageLines.set(7,imageLines.get(7) + " §8§m=========================="); + Bukkit.broadcastMessage("\n"); + Bukkit.broadcastMessage(String.join("\n", imageLines)); + Bukkit.broadcastMessage("\n"); + } + + @Override + public void dispatchCompletions(CommandSender sender, Command command, String label, CompletionBuilder b) { + b.then( + b.argOnlinePlayers() + .then( + b.argInt("amount") + .then( + b.argDecimal("price") + .then( + b.arg("Item") + ) + ) + ) + ); + } +} diff --git a/src/main/java/me/trouper/trimalias/server/commands/ManageCommand.java b/src/main/java/me/trouper/trimalias/server/commands/ManageCommand.java index d7ffa49..cdb5d8a 100644 --- a/src/main/java/me/trouper/trimalias/server/commands/ManageCommand.java +++ b/src/main/java/me/trouper/trimalias/server/commands/ManageCommand.java @@ -108,7 +108,7 @@ public class ManageCommand implements QuickCommand { .then( b.argOnlinePlayers() .then( - b.arg("default", "helper", "moderator", "admin", "owner") + b.argEnum(ValidStaff.class) ) ) ); diff --git a/src/main/java/me/trouper/trimalias/server/commands/RankCommand.java b/src/main/java/me/trouper/trimalias/server/commands/RankCommand.java index 0f930a0..8de3104 100644 --- a/src/main/java/me/trouper/trimalias/server/commands/RankCommand.java +++ b/src/main/java/me/trouper/trimalias/server/commands/RankCommand.java @@ -77,7 +77,7 @@ public class RankCommand implements QuickCommand { .then( b.argOnlinePlayers() .then( - b.arg(LuckPermsUtils.getGroups()) + b.argEnum(ValidRank.class) .then( b.arg("lifetime","season") ) diff --git a/src/main/java/me/trouper/trimalias/server/events/ConnectEvent.java b/src/main/java/me/trouper/trimalias/server/events/ConnectEvent.java new file mode 100644 index 0000000..edcb5c1 --- /dev/null +++ b/src/main/java/me/trouper/trimalias/server/events/ConnectEvent.java @@ -0,0 +1,41 @@ +package me.trouper.trimalias.server.events; + +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerLoginEvent; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +public class ConnectEvent implements QuickListener { + private final Map loginTimestamps = new ConcurrentHashMap<>(); + + @EventHandler + public void onAsyncPreLogin(AsyncPlayerPreLoginEvent event) { + String address = event.getAddress().getHostAddress(); + + if (isOperator(event.getUniqueId())) { + return; + } + + long now = System.currentTimeMillis(); + long last = loginTimestamps.getOrDefault(address, 0L); + + if (now - last < 4000) { + event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Component.text("You're logging in too fast.")); + } else { + loginTimestamps.put(address, now); + } + } + + private boolean isOperator(UUID uuid) { + OfflinePlayer player = Bukkit.getOfflinePlayer(uuid); + return player.isOp(); + } + +} diff --git a/src/main/java/me/trouper/trimalias/utils/Text.java b/src/main/java/me/trouper/trimalias/utils/Text.java index f71735c..c5f4f77 100755 --- a/src/main/java/me/trouper/trimalias/utils/Text.java +++ b/src/main/java/me/trouper/trimalias/utils/Text.java @@ -6,11 +6,16 @@ import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Color; import org.bukkit.Sound; import org.bukkit.SoundCategory; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.net.URL; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -309,4 +314,33 @@ public class Text implements Main { } return result; } + + public static List imageToList(String url) { + try { + URL uri = new URL(url); + BufferedImage img = ImageIO.read(uri); + List lines = new ArrayList<>(); + StringBuilder message = new StringBuilder(); + int width = 0; + + for (int y = 0; y < img.getHeight(); y++) { + for (int x = 0; x < img.getWidth(); x++) { + int rgb = img.getRGB(x, y); + Color color = Color.fromARGB(rgb); + String hex = color.toString().replaceAll("Color:\\[argb0xFF", "").replaceAll("\\]", ""); + ChatColor chat = ChatColor.of("#" + hex); + message.append(chat).append("█"); + + if ((width++) >= 7) { + lines.add(message.toString()); + message = new StringBuilder(); + width = 0; + } + } + } + return lines; + } catch (Exception e) { + return new ArrayList<>(); + } + } } \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0bec121..935d5cb 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -24,6 +24,10 @@ commands: usage: /copyinv permission: trimalias.copyinv description: Copy the inventory of a player + broadcastdonation: + usage: /broadcastdonatio + permission: trimalias.broadcast + description: Show a stylized donation message in chat permissions: trimalias.rank: @@ -43,4 +47,6 @@ permissions: trimalias.spawn.bypass: description: Bypasses the spawn cooldown and warmup trimalias.copyinv: - description: Allows getting all items from a player inventory \ No newline at end of file + description: Allows getting all items from a player inventory + trimalias.broadcast: + description: Broadcast donations \ No newline at end of file