feat: add social commands, MetricsCollector, moderation commands to feature packages
This commit is contained in:
parent
63f8763ff9
commit
fcb5cd7207
14 changed files with 1328 additions and 0 deletions
|
|
@ -0,0 +1,78 @@
|
||||||
|
package creator.loki.command.impl.entertainment.interaction.negative;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedFactory;
|
||||||
|
import creator.loki.core.security.CooldownManager;
|
||||||
|
import creator.loki.integration.nekos.NekosLifeApi;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Тыкнуть пользователя с GIF
|
||||||
|
*/
|
||||||
|
public class PokeCommand implements Command {
|
||||||
|
|
||||||
|
private final CooldownManager cooldownManager;
|
||||||
|
|
||||||
|
public PokeCommand(CooldownManager cooldownManager) {
|
||||||
|
this.cooldownManager = cooldownManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "poke";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Тыкнуть пользователя";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "poke <@user>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Развлечения";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
if (cooldownManager.isOnCooldown(context.getAuthor().getId(), "poke")) {
|
||||||
|
long remaining = cooldownManager.getRemainingSeconds(context.getAuthor().getId(), "poke");
|
||||||
|
context.getChannel().sendMessage("⏰ Подожди ещё " + remaining + " сек").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessage("❌ Укажи пользователя через @").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
|
||||||
|
cooldownManager.applyCooldown(context.getAuthor().getId(), "poke", 5);
|
||||||
|
|
||||||
|
String gifUrl = NekosLifeApi.fetchImage("poke");
|
||||||
|
|
||||||
|
if (gifUrl == null) {
|
||||||
|
context.getChannel().sendMessage("❌ Не удалось получить изображение!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedFactory.create()
|
||||||
|
.setDescription("👉 " + context.getAuthor().getAsMention() + " тыкает в " + target.getAsMention() + "! 😏")
|
||||||
|
.setImage(gifUrl)
|
||||||
|
.setColor(new Color(0, 128, 128))
|
||||||
|
.setFooter("Powered by nekos.life")
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
package creator.loki.command.impl.entertainment.interaction;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedFactory;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class RoastCommand implements Command {
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
|
private static final String[] ROASTS = {
|
||||||
|
"Ты как Internet Explorer — медленный и никому не нужный",
|
||||||
|
"Твой код работает? Это баг, исправь его",
|
||||||
|
"Ты пишешь код как будто тебе за каждую строку платят",
|
||||||
|
"Твоя логика как у JavaScript: непредсказуемая",
|
||||||
|
"Ты как HTML без CSS — работаешь, но выглядишь ужасно",
|
||||||
|
"Твой IQ как температура в Антарктиде — ниже нуля",
|
||||||
|
"Ты как баг в продакшене — неожиданный и нежеланный",
|
||||||
|
"Твои шутки как deprecated код — устарели",
|
||||||
|
"Ты как NULL pointer — бесполезный и вызываешь ошибки",
|
||||||
|
"Твой уровень как индекс массива в Python — может быть отрицательным"
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "roast";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Дружеский рофл над пользователем";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "roast <@user>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Развлечения";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessage("Укажи пользователя через @").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
String roast = ROASTS[random.nextInt(ROASTS.length)];
|
||||||
|
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedFactory.create()
|
||||||
|
.setTitle("🔥 Roast")
|
||||||
|
.setDescription(target.getAsMention() + ", " + roast)
|
||||||
|
.setColor(new Color(231, 76, 60))
|
||||||
|
.setFooter("Это шутка, не обижайся!")
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package creator.loki.command.impl.entertainment.interaction.negative;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedFactory;
|
||||||
|
import creator.loki.core.security.CooldownManager;
|
||||||
|
import creator.loki.integration.nekos.NekosLifeApi;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Шлепнуть пользователя с GIF
|
||||||
|
*/
|
||||||
|
public class SlapCommand implements Command {
|
||||||
|
|
||||||
|
private final CooldownManager cooldownManager;
|
||||||
|
|
||||||
|
public SlapCommand(CooldownManager cooldownManager) {
|
||||||
|
this.cooldownManager = cooldownManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "slap";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Шлепнуть пользователя";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "slap <@user>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Развлечения";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
if (cooldownManager.isOnCooldown(context.getAuthor().getId(), "slap")) {
|
||||||
|
long remaining = cooldownManager.getRemainingSeconds(context.getAuthor().getId(), "slap");
|
||||||
|
context.getChannel().sendMessage("⏰ Подожди ещё " + remaining + " сек").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessage("❌ Укажи пользователя через @").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
|
||||||
|
cooldownManager.applyCooldown(context.getAuthor().getId(), "slap", 5);
|
||||||
|
|
||||||
|
String gifUrl = NekosLifeApi.fetchImage("slap");
|
||||||
|
|
||||||
|
if (gifUrl == null) {
|
||||||
|
context.getChannel().sendMessage("❌ Не удалось получить изображение!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedFactory.create()
|
||||||
|
.setDescription("👋 " + context.getAuthor().getAsMention() + " шлепает " + target.getAsMention() + "! 😠")
|
||||||
|
.setImage(gifUrl)
|
||||||
|
.setColor(new Color(255, 165, 0))
|
||||||
|
.setFooter("Powered by nekos.life")
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package creator.loki.command.impl.entertainment.interaction.negative;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedFactory;
|
||||||
|
import creator.loki.core.security.CooldownManager;
|
||||||
|
import creator.loki.integration.nekos.NekosLifeApi;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Пощекотать пользователя с GIF
|
||||||
|
*/
|
||||||
|
public class TickleCommand implements Command {
|
||||||
|
|
||||||
|
private final CooldownManager cooldownManager;
|
||||||
|
|
||||||
|
public TickleCommand(CooldownManager cooldownManager) {
|
||||||
|
this.cooldownManager = cooldownManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "tickle";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Пощекотать пользователя";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "tickle <@user>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Развлечения";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
if (cooldownManager.isOnCooldown(context.getAuthor().getId(), "tickle")) {
|
||||||
|
long remaining = cooldownManager.getRemainingSeconds(context.getAuthor().getId(), "tickle");
|
||||||
|
context.getChannel().sendMessage("⏰ Подожди ещё " + remaining + " сек").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessage("❌ Укажи пользователя через @").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
|
||||||
|
cooldownManager.applyCooldown(context.getAuthor().getId(), "tickle", 5);
|
||||||
|
|
||||||
|
String gifUrl = NekosLifeApi.fetchImage("tickle");
|
||||||
|
|
||||||
|
if (gifUrl == null) {
|
||||||
|
context.getChannel().sendMessage("❌ Не удалось получить изображение!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedFactory.create()
|
||||||
|
.setDescription("🤗 " + context.getAuthor().getAsMention() + " щекочет " + target.getAsMention() + "!")
|
||||||
|
.setImage(gifUrl)
|
||||||
|
.setColor(new Color(0, 255, 0))
|
||||||
|
.setFooter("Powered by nekos.life")
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
package creator.loki.command.impl.entertainment.interaction;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedFactory;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class ComplimentCommand implements Command {
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
|
private static final String[] COMPLIMENTS = {
|
||||||
|
"Ты как идеальный код — красивый и без багов",
|
||||||
|
"Твоя улыбка ярче, чем RGB подсветка",
|
||||||
|
"Ты как хороший коммит — делаешь всё лучше",
|
||||||
|
"Твой вайб как у Python — простой и приятный",
|
||||||
|
"Ты как успешный деплой — всё работает отлично",
|
||||||
|
"Твоя энергия как у SSD — быстрая и эффективная",
|
||||||
|
"Ты как open source проект — полезный для всех",
|
||||||
|
"Твоя харизма как у TypeScript — добавляет уверенности",
|
||||||
|
"Ты как хороший API — понятный и надёжный",
|
||||||
|
"Твоё присутствие как кофе для программиста — необходимо"
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "compliment";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Сделать комплимент пользователю";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "compliment <@user>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Развлечения";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessage("Укажи пользователя через @").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
String compliment = COMPLIMENTS[random.nextInt(COMPLIMENTS.length)];
|
||||||
|
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedFactory.create()
|
||||||
|
.setTitle("💖 Комплимент")
|
||||||
|
.setDescription(target.getAsMention() + ", " + compliment)
|
||||||
|
.setColor(new Color(255, 182, 193))
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package creator.loki.command.impl.entertainment.interaction.positive;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedFactory;
|
||||||
|
import creator.loki.core.security.CooldownManager;
|
||||||
|
import creator.loki.integration.nekos.NekosLifeApi;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Обниматься с пользователем с GIF
|
||||||
|
*/
|
||||||
|
public class CuddleCommand implements Command {
|
||||||
|
|
||||||
|
private final CooldownManager cooldownManager;
|
||||||
|
|
||||||
|
public CuddleCommand(CooldownManager cooldownManager) {
|
||||||
|
this.cooldownManager = cooldownManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "cuddle";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Обниматься с пользователем";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "cuddle <@user>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Развлечения";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
if (cooldownManager.isOnCooldown(context.getAuthor().getId(), "cuddle")) {
|
||||||
|
long remaining = cooldownManager.getRemainingSeconds(context.getAuthor().getId(), "cuddle");
|
||||||
|
context.getChannel().sendMessage("⏰ Подожди ещё " + remaining + " сек").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessage("❌ Укажи пользователя через @").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
|
||||||
|
cooldownManager.applyCooldown(context.getAuthor().getId(), "cuddle", 5);
|
||||||
|
|
||||||
|
String gifUrl = NekosLifeApi.fetchImage("cuddle");
|
||||||
|
|
||||||
|
if (gifUrl == null) {
|
||||||
|
context.getChannel().sendMessage("❌ Не удалось получить изображение!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedFactory.create()
|
||||||
|
.setDescription("🥰 " + context.getAuthor().getAsMention() + " обнимается с " + target.getAsMention() + "! 💕")
|
||||||
|
.setImage(gifUrl)
|
||||||
|
.setColor(new Color(255, 0, 255))
|
||||||
|
.setFooter("Powered by nekos.life")
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package creator.loki.command.impl.entertainment.interaction.positive;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedFactory;
|
||||||
|
import creator.loki.core.security.CooldownManager;
|
||||||
|
import creator.loki.integration.nekos.NekosLifeApi;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Покормить пользователя с GIF
|
||||||
|
*/
|
||||||
|
public class FeedCommand implements Command {
|
||||||
|
|
||||||
|
private final CooldownManager cooldownManager;
|
||||||
|
|
||||||
|
public FeedCommand(CooldownManager cooldownManager) {
|
||||||
|
this.cooldownManager = cooldownManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "feed";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Покормить пользователя";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "feed <@user>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Развлечения";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
if (cooldownManager.isOnCooldown(context.getAuthor().getId(), "feed")) {
|
||||||
|
long remaining = cooldownManager.getRemainingSeconds(context.getAuthor().getId(), "feed");
|
||||||
|
context.getChannel().sendMessage("⏰ Подожди ещё " + remaining + " сек").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessage("❌ Укажи пользователя через @").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
|
||||||
|
cooldownManager.applyCooldown(context.getAuthor().getId(), "feed", 5);
|
||||||
|
|
||||||
|
String gifUrl = NekosLifeApi.fetchImage("feed");
|
||||||
|
|
||||||
|
if (gifUrl == null) {
|
||||||
|
context.getChannel().sendMessage("❌ Не удалось получить изображение!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedFactory.create()
|
||||||
|
.setDescription("🍽️ " + context.getAuthor().getAsMention() + " кормит " + target.getAsMention() + "! 😋")
|
||||||
|
.setImage(gifUrl)
|
||||||
|
.setColor(new Color(255, 200, 100))
|
||||||
|
.setFooter("Powered by nekos.life")
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package creator.loki.command.impl.entertainment.interaction.positive;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedFactory;
|
||||||
|
import creator.loki.integration.nekos.NekosLifeApi;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HugCommand implements Command {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "hug";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Обнять пользователя";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "hug <@user>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Развлечения";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessage("❌ Укажи пользователя через @").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
|
||||||
|
// Получаем GIF из nekos.life API
|
||||||
|
String gifUrl = NekosLifeApi.fetchImage("hug");
|
||||||
|
|
||||||
|
if (gifUrl == null) {
|
||||||
|
context.getChannel().sendMessage("❌ Не удалось получить изображение!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedFactory.create()
|
||||||
|
.setDescription("🤗 " + context.getAuthor().getAsMention() + " обнял " + target.getAsMention() + " 💕")
|
||||||
|
.setImage(gifUrl)
|
||||||
|
.setColor(new Color(255, 182, 193))
|
||||||
|
.setFooter("Powered by nekos.life")
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
package creator.loki.command.impl.entertainment.interaction.positive;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedFactory;
|
||||||
|
import creator.loki.core.security.CooldownManager;
|
||||||
|
import creator.loki.integration.nekos.NekosLifeApi;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поцелуй пользователя с GIF
|
||||||
|
*/
|
||||||
|
public class KissCommand implements Command {
|
||||||
|
|
||||||
|
private final CooldownManager cooldownManager;
|
||||||
|
|
||||||
|
public KissCommand(CooldownManager cooldownManager) {
|
||||||
|
this.cooldownManager = cooldownManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "kiss";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Поцеловать пользователя";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "kiss <@user>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Развлечения";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
// Проверка cooldown (5 секунд)
|
||||||
|
if (cooldownManager.isOnCooldown(context.getAuthor().getId(), "kiss")) {
|
||||||
|
long remaining = cooldownManager.getRemainingSeconds(context.getAuthor().getId(), "kiss");
|
||||||
|
context.getChannel().sendMessage("⏰ Подожди ещё " + remaining + " сек").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessage("❌ Укажи кого поцеловать! Использование: `!kiss @user`").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
|
||||||
|
if (target.getId().equals(context.getAuthor().getId())) {
|
||||||
|
context.getChannel().sendMessage("❌ Нельзя целовать самого себя!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.getUser().isBot()) {
|
||||||
|
context.getChannel().sendMessage("❌ Боты не умеют целоваться!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Применяем cooldown
|
||||||
|
cooldownManager.applyCooldown(context.getAuthor().getId(), "kiss", 5);
|
||||||
|
|
||||||
|
// Получаем GIF из nekos.life API
|
||||||
|
String gifUrl = NekosLifeApi.fetchImage("kiss");
|
||||||
|
|
||||||
|
if (gifUrl == null) {
|
||||||
|
context.getChannel().sendMessage("❌ Не удалось получить изображение!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedFactory.create()
|
||||||
|
.setDescription("💋 " + context.getAuthor().getAsMention() + " целует " + target.getAsMention() + " ❤️")
|
||||||
|
.setImage(gifUrl)
|
||||||
|
.setColor(new Color(255, 105, 180))
|
||||||
|
.setFooter("Powered by nekos.life")
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
package creator.loki.command.impl.entertainment.interaction.positive;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.core.security.CooldownManager;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PatCommand implements Command {
|
||||||
|
private static final int COOLDOWN_SECONDS = 5;
|
||||||
|
private final CooldownManager cooldownManager;
|
||||||
|
|
||||||
|
public PatCommand(CooldownManager cooldownManager) {
|
||||||
|
this.cooldownManager = cooldownManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "pat";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Погладить пользователя";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "pat <@user> <количество 1-7>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Развлечения";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
String userId = context.getAuthor().getId();
|
||||||
|
|
||||||
|
// Проверка cooldown
|
||||||
|
if (cooldownManager.isOnCooldown(userId, "pat")) {
|
||||||
|
long remaining = cooldownManager.getRemainingSeconds(userId, "pat");
|
||||||
|
context.getChannel().sendMessage(
|
||||||
|
"⏰ Подожди " + remaining + " сек."
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка аргументов
|
||||||
|
if (context.getArgs().size() < 2) {
|
||||||
|
context.getChannel().sendMessage(
|
||||||
|
"❌ Используй: `!pat <@user> <количество 1-7>`"
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение упомянутого пользователя
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessage("❌ Укажи пользователя через @").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
|
||||||
|
// Парсинг количества
|
||||||
|
int count;
|
||||||
|
try {
|
||||||
|
count = Integer.parseInt(context.getArgs().get(1));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
context.getChannel().sendMessage("❌ Укажи число от 1 до 7").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Валидация количества
|
||||||
|
if (count < 1 || count > 7) {
|
||||||
|
context.getChannel().sendMessage("❌ Количество должно быть от 1 до 7").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Применяем cooldown
|
||||||
|
cooldownManager.applyCooldown(userId, "pat", COOLDOWN_SECONDS);
|
||||||
|
|
||||||
|
// Отправляем каждое "pat-pat" отдельным сообщением
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
context.getChannel().sendMessage("pat-pat " + target.getAsMention()).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
203
src/main/java/creator/loki/feature/metrics/MetricsCollector.java
Normal file
203
src/main/java/creator/loki/feature/metrics/MetricsCollector.java
Normal file
|
|
@ -0,0 +1,203 @@
|
||||||
|
package creator.loki.feature.metrics;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сборщик метрик для мониторинга бота
|
||||||
|
*/
|
||||||
|
public class MetricsCollector {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(MetricsCollector.class);
|
||||||
|
|
||||||
|
// Счётчики команд
|
||||||
|
private final ConcurrentHashMap<String, LongAdder> commandCounts = new ConcurrentHashMap<>();
|
||||||
|
private final ConcurrentHashMap<String, LongAdder> commandErrors = new ConcurrentHashMap<>();
|
||||||
|
private final ConcurrentHashMap<String, AtomicLong> commandTotalTime = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// Общие метрики
|
||||||
|
private final LongAdder totalCommands = new LongAdder();
|
||||||
|
private final LongAdder totalErrors = new LongAdder();
|
||||||
|
private final AtomicLong startTime = new AtomicLong(System.currentTimeMillis());
|
||||||
|
|
||||||
|
public MetricsCollector() {
|
||||||
|
logger.info("MetricsCollector инициализирован");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Записывает выполнение команды
|
||||||
|
*/
|
||||||
|
public void recordCommand(String commandName, long executionTimeMs) {
|
||||||
|
commandCounts.computeIfAbsent(commandName, k -> new LongAdder()).increment();
|
||||||
|
commandTotalTime.computeIfAbsent(commandName, k -> new AtomicLong()).addAndGet(executionTimeMs);
|
||||||
|
totalCommands.increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Записывает ошибку команды
|
||||||
|
*/
|
||||||
|
public void recordError(String commandName) {
|
||||||
|
commandErrors.computeIfAbsent(commandName, k -> new LongAdder()).increment();
|
||||||
|
totalErrors.increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает количество выполнений команды
|
||||||
|
*/
|
||||||
|
public long getCommandCount(String commandName) {
|
||||||
|
LongAdder counter = commandCounts.get(commandName);
|
||||||
|
return counter != null ? counter.sum() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает количество ошибок команды
|
||||||
|
*/
|
||||||
|
public long getCommandErrors(String commandName) {
|
||||||
|
LongAdder counter = commandErrors.get(commandName);
|
||||||
|
return counter != null ? counter.sum() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает среднее время выполнения команды
|
||||||
|
*/
|
||||||
|
public double getAverageExecutionTime(String commandName) {
|
||||||
|
long count = getCommandCount(commandName);
|
||||||
|
if (count == 0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
AtomicLong totalTime = commandTotalTime.get(commandName);
|
||||||
|
if (totalTime == null) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
return (double) totalTime.get() / count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает общее количество выполненных команд
|
||||||
|
*/
|
||||||
|
public long getTotalCommands() {
|
||||||
|
return totalCommands.sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает общее количество ошибок
|
||||||
|
*/
|
||||||
|
public long getTotalErrors() {
|
||||||
|
return totalErrors.sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает процент ошибок
|
||||||
|
*/
|
||||||
|
public double getErrorRate() {
|
||||||
|
long total = getTotalCommands();
|
||||||
|
if (total == 0) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
return (double) getTotalErrors() / total * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает время работы бота в секундах
|
||||||
|
*/
|
||||||
|
public long getUptimeSeconds() {
|
||||||
|
return (System.currentTimeMillis() - startTime.get()) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON для {@code GET /health} (пробы оркестраторов).
|
||||||
|
*/
|
||||||
|
public String buildHealthJson() {
|
||||||
|
String version = Optional.ofNullable(MetricsCollector.class.getPackage().getImplementationVersion())
|
||||||
|
.filter(v -> !v.isBlank())
|
||||||
|
.orElse("dev");
|
||||||
|
return String.format(Locale.ROOT,
|
||||||
|
"{\"status\":\"ok\",\"version\":%s,\"uptimeSeconds\":%d,\"commandsRun\":%d,\"errors\":%d,\"errorRatePercent\":%.4f}",
|
||||||
|
jsonQuoted(version),
|
||||||
|
getUptimeSeconds(),
|
||||||
|
getTotalCommands(),
|
||||||
|
getTotalErrors(),
|
||||||
|
getErrorRate());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String jsonQuoted(String s) {
|
||||||
|
StringBuilder sb = new StringBuilder(s.length() + 2);
|
||||||
|
sb.append('"');
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
switch (c) {
|
||||||
|
case '\\' -> sb.append("\\\\");
|
||||||
|
case '"' -> sb.append("\\\"");
|
||||||
|
case '\n' -> sb.append("\\n");
|
||||||
|
case '\r' -> sb.append("\\r");
|
||||||
|
case '\t' -> sb.append("\\t");
|
||||||
|
default -> sb.append(c < ' ' ? ' ' : c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append('"');
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает топ команд по использованию
|
||||||
|
*/
|
||||||
|
public String getTopCommands(int limit) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("📊 Топ команд:\n");
|
||||||
|
|
||||||
|
commandCounts.entrySet().stream()
|
||||||
|
.sorted((e1, e2) -> Long.compare(e2.getValue().sum(), e1.getValue().sum()))
|
||||||
|
.limit(limit)
|
||||||
|
.forEach(entry -> {
|
||||||
|
String cmd = entry.getKey();
|
||||||
|
long count = entry.getValue().sum();
|
||||||
|
long errors = getCommandErrors(cmd);
|
||||||
|
double avgTime = getAverageExecutionTime(cmd);
|
||||||
|
|
||||||
|
sb.append(String.format(" %s: %d выполнений, %.1f мс среднее, %d ошибок\n",
|
||||||
|
cmd, count, avgTime, errors));
|
||||||
|
});
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Возвращает полную статистику
|
||||||
|
*/
|
||||||
|
public String getFullStats() {
|
||||||
|
long uptime = getUptimeSeconds();
|
||||||
|
long hours = uptime / 3600;
|
||||||
|
long minutes = (uptime % 3600) / 60;
|
||||||
|
long seconds = uptime % 60;
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("📈 Статистика бота\n");
|
||||||
|
sb.append("━━━━━━━━━━━━━━━━━━━━\n");
|
||||||
|
sb.append(String.format("⏱️ Uptime: %dч %dм %dс\n", hours, minutes, seconds));
|
||||||
|
sb.append(String.format("📝 Всего команд: %d\n", getTotalCommands()));
|
||||||
|
sb.append(String.format("❌ Всего ошибок: %d (%.2f%%)\n", getTotalErrors(), getErrorRate()));
|
||||||
|
sb.append(String.format("📊 Уникальных команд: %d\n", commandCounts.size()));
|
||||||
|
sb.append("\n");
|
||||||
|
sb.append(getTopCommands(10));
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сбрасывает все метрики
|
||||||
|
*/
|
||||||
|
public void reset() {
|
||||||
|
commandCounts.clear();
|
||||||
|
commandErrors.clear();
|
||||||
|
commandTotalTime.clear();
|
||||||
|
totalCommands.reset();
|
||||||
|
totalErrors.reset();
|
||||||
|
startTime.set(System.currentTimeMillis());
|
||||||
|
logger.info("Метрики сброшены");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
package creator.loki.feature.moderation.commands;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedTemplates;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BanCommand implements Command {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "ban";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Банит пользователя на сервере";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "ban <@user> [причина]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Модерация";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
if (context.getGuild() == null) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Ошибка", "Команда доступна только на сервере")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка прав модератора
|
||||||
|
if (context.getAuthor() == null || !context.getAuthor().hasPermission(Permission.BAN_MEMBERS)) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Недостаточно прав", "У вас нет прав на бан пользователей")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка прав бота
|
||||||
|
if (!context.getGuild().getSelfMember().hasPermission(Permission.BAN_MEMBERS)) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Недостаточно прав", "У бота нет прав на бан пользователей")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получение упомянутого пользователя
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Ошибка", "Укажите пользователя через @")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
|
||||||
|
// Нельзя забанить самого себя
|
||||||
|
if (target.getId().equals(context.getAuthor().getId())) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Ошибка", "Вы не можете забанить самого себя")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Нельзя забанить бота
|
||||||
|
if (target.getUser().isBot() && target.getId().equals(context.getGuild().getSelfMember().getId())) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Ошибка", "Я не могу забанить самого себя")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка иерархии ролей
|
||||||
|
if (!context.getAuthor().canInteract(target)) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Недостаточно прав", "Вы не можете забанить этого пользователя (роль выше вашей)")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context.getGuild().getSelfMember().canInteract(target)) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Недостаточно прав", "Я не могу забанить этого пользователя (роль выше моей)")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Причина бана
|
||||||
|
String reason = context.getArgs().size() > 1
|
||||||
|
? String.join(" ", context.getArgs().subList(1, context.getArgs().size()))
|
||||||
|
: "Причина не указана";
|
||||||
|
|
||||||
|
// Бан
|
||||||
|
context.getGuild().ban(target, 0, java.util.concurrent.TimeUnit.DAYS)
|
||||||
|
.reason(reason)
|
||||||
|
.queue(
|
||||||
|
success -> {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.success(
|
||||||
|
"Пользователь забанен",
|
||||||
|
"**Пользователь:** " + target.getUser().getGlobalName() + "\n" +
|
||||||
|
"**Причина:** " + reason + "\n" +
|
||||||
|
"**Модератор:** " + context.getAuthor().getAsMention()
|
||||||
|
)
|
||||||
|
).queue();
|
||||||
|
},
|
||||||
|
error -> {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error(
|
||||||
|
"Ошибка",
|
||||||
|
"Не удалось забанить. Проверь права бота, иерархию ролей и что участник на сервере."
|
||||||
|
)
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
package creator.loki.feature.moderation.commands;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedTemplates;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class ClearCommand implements Command {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "clear";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Удаляет указанное количество сообщений";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "clear <количество>";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
// Проверка прав
|
||||||
|
if (context.getAuthor() == null || !context.getAuthor().hasPermission(Permission.MESSAGE_MANAGE)) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error(
|
||||||
|
"Недостаточно прав",
|
||||||
|
"У вас нет прав на управление сообщениями"
|
||||||
|
)
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка аргументов
|
||||||
|
if (context.getArgs().isEmpty()) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error(
|
||||||
|
"Неверное количество",
|
||||||
|
"Укажите число от 1 до 100"
|
||||||
|
)
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int amount;
|
||||||
|
try {
|
||||||
|
amount = Integer.parseInt(context.getArgs().get(0));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error(
|
||||||
|
"Неверное количество",
|
||||||
|
"Укажите число от 1 до 100"
|
||||||
|
)
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount < 1 || amount > 100) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error(
|
||||||
|
"Неверное количество",
|
||||||
|
"Укажите число от 1 до 100"
|
||||||
|
)
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Удаление сообщений
|
||||||
|
if (!(context.getChannel() instanceof TextChannel channel)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
channel.getHistory().retrievePast(amount + 1).queue(messages -> {
|
||||||
|
channel.deleteMessages(messages).queue(
|
||||||
|
success -> {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.success(
|
||||||
|
"Сообщения удалены",
|
||||||
|
"Удалено сообщений: " + messages.size()
|
||||||
|
)
|
||||||
|
).queue(msg -> msg.delete().queueAfter(5, TimeUnit.SECONDS));
|
||||||
|
},
|
||||||
|
error -> {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error(
|
||||||
|
"Ошибка удаления",
|
||||||
|
"Не удалось удалить сообщения: " + error.getMessage()
|
||||||
|
)
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Модерация";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
package creator.loki.feature.moderation.commands;
|
||||||
|
|
||||||
|
import creator.loki.command.Command;
|
||||||
|
import creator.loki.command.CommandContext;
|
||||||
|
import creator.loki.embed.EmbedTemplates;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class KickCommand implements Command {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "kick";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Кикает пользователя с сервера";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsage() {
|
||||||
|
return "kick <@user> [причина]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCategory() {
|
||||||
|
return "Модерация";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandContext context) {
|
||||||
|
if (context.getGuild() == null) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Ошибка", "Команда доступна только на сервере")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.getAuthor() == null || !context.getAuthor().hasPermission(Permission.KICK_MEMBERS)) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Недостаточно прав", "У вас нет прав на кик пользователей")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context.getGuild().getSelfMember().hasPermission(Permission.KICK_MEMBERS)) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Недостаточно прав", "У бота нет прав на кик пользователей")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Member> mentioned = context.getMessage().getMentions().getMembers();
|
||||||
|
if (mentioned.isEmpty()) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Ошибка", "Укажите пользователя через @")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member target = mentioned.get(0);
|
||||||
|
|
||||||
|
if (target.getId().equals(context.getAuthor().getId())) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Ошибка", "Вы не можете кикнуть самого себя")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.getUser().isBot() && target.getId().equals(context.getGuild().getSelfMember().getId())) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Ошибка", "Я не могу кикнуть самого себя")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context.getAuthor().canInteract(target)) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Недостаточно прав", "Вы не можете кикнуть этого пользователя")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context.getGuild().getSelfMember().canInteract(target)) {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error("Недостаточно прав", "Я не могу кикнуть этого пользователя")
|
||||||
|
).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String reason = context.getArgs().size() > 1
|
||||||
|
? String.join(" ", context.getArgs().subList(1, context.getArgs().size()))
|
||||||
|
: "Причина не указана";
|
||||||
|
|
||||||
|
context.getGuild().kick(target)
|
||||||
|
.reason(reason)
|
||||||
|
.queue(
|
||||||
|
success -> {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.success(
|
||||||
|
"Пользователь кикнут",
|
||||||
|
"**Пользователь:** " + target.getUser().getGlobalName() + "\n" +
|
||||||
|
"**Причина:** " + reason + "\n" +
|
||||||
|
"**Модератор:** " + context.getAuthor().getAsMention()
|
||||||
|
)
|
||||||
|
).queue();
|
||||||
|
},
|
||||||
|
error -> {
|
||||||
|
context.getChannel().sendMessageEmbeds(
|
||||||
|
EmbedTemplates.error(
|
||||||
|
"Ошибка",
|
||||||
|
"Не удалось кикнуть. Проверь права бота (**Kick Members**), иерархию ролей и что участник не выше бота."
|
||||||
|
)
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue