feat: +5 meter команд + !timer

- !simp — симп-детектор (💀/⬜)
- !vibe — вайб-чек (🎵/⬜)
- !glaze — глазурь-метр (🍩/⬜)
- !goon — гуон-детектор (💀/⬜)
- !timer <сек> — таймер с упоминанием (virtual thread)
- RatingConfig: уровни для simp/vibe/glaze
- Всего 15 meter-команд
This commit is contained in:
loki5512344 2026-07-04 23:04:39 +02:00
parent d981a2eea5
commit 80863a9592
8 changed files with 234 additions and 3 deletions

View file

@ -15,12 +15,16 @@ import creator.loki.feature.rating.commands.AuraCommand;
import creator.loki.feature.rating.commands.BoykisserCommand;
import creator.loki.feature.rating.commands.FatCommand;
import creator.loki.feature.rating.commands.GayCommand;
import creator.loki.feature.rating.commands.GlazeCommand;
import creator.loki.feature.rating.commands.GoonCommand;
import creator.loki.feature.rating.commands.IqCommand;
import creator.loki.feature.rating.commands.LuckCommand;
import creator.loki.feature.rating.commands.MustacheCommand;
import creator.loki.feature.rating.commands.PpCommand;
import creator.loki.feature.rating.commands.RateCommand;
import creator.loki.feature.rating.commands.RizzCommand;
import creator.loki.feature.rating.commands.SimpCommand;
import creator.loki.feature.rating.commands.VibeCommand;
import creator.loki.feature.entertainment.service.RatingService;
import creator.loki.feature.ship.ShipCommand;
import creator.loki.feature.ship.repository.ShipPairRepository;
@ -68,6 +72,10 @@ public class EntertainmentCommandRegistrar implements CommandRegistrar {
registry.register(new RizzCommand(ratingService));
registry.register(new LuckCommand(ratingService));
registry.register(new AuraCommand(ratingService));
registry.register(new SimpCommand(ratingService));
registry.register(new VibeCommand(ratingService));
registry.register(new GlazeCommand(ratingService));
registry.register(new GoonCommand(ratingService));
registry.register(new PatCommand(cooldownManager));
for (var flavor : SocialCommand.Flavor.values()) {

View file

@ -0,0 +1,40 @@
package creator.loki.feature.rating.commands;
import com.google.inject.Inject;
import creator.loki.command.Command;
import creator.loki.command.CommandContext;
import creator.loki.embed.EmbedFactory;
import creator.loki.feature.entertainment.service.RatingService;
import creator.loki.feature.rating.config.RatingConfig;
import creator.loki.feature.rating.config.RatingLevel;
import net.dv8tion.jda.api.entities.Member;
public class GlazeCommand implements Command {
private final RatingService ratingService;
@Inject
public GlazeCommand(RatingService ratingService) { this.ratingService = ratingService; }
@Override public String getName() { return "glaze"; }
@Override public String getDescription() { return "На сколько ты глазированный (результат всегда одинаковый)"; }
@Override public String getUsage() { return "glaze [@user]"; }
@Override public String getCategory() { return "Развлечения"; }
@Override
public void execute(CommandContext context) {
if (!ratingService.checkAndApplyCooldown(context, "glaze")) return;
Member target = ratingService.resolveTarget(context);
if (target == null) return;
int level = ratingService.getDeterministicValue(target.getId(), 333, 0, 100);
StringBuilder bar = new StringBuilder();
int filled = level / 10;
for (int i = 0; i < filled; i++) bar.append("🍩");
for (int i = filled; i < 10; i++) bar.append("⬜");
RatingLevel rl = RatingLevel.findLevel(level, RatingConfig.getGlazeLevels());
context.getChannel().sendMessageEmbeds(
EmbedFactory.create().withTitle("🍩 Глазурь-метр").withDescription(target.getAsMention())
.addField("Глазурь", bar + "\n**" + level + "%** - " + rl.getComment(), false)
.withThumbnail(target.getUser().getAvatarUrl()).withColor(rl.getColor())
.withFooter("💡 Детерминировано вашим Discord ID").build()).queue();
}
}

View file

@ -0,0 +1,40 @@
package creator.loki.feature.rating.commands;
import java.awt.Color;
import com.google.inject.Inject;
import creator.loki.command.Command;
import creator.loki.command.CommandContext;
import creator.loki.embed.EmbedFactory;
import creator.loki.feature.entertainment.service.RatingService;
import net.dv8tion.jda.api.entities.Member;
public class GoonCommand implements Command {
private final RatingService ratingService;
@Inject
public GoonCommand(RatingService ratingService) { this.ratingService = ratingService; }
@Override public String getName() { return "goon"; }
@Override public String getDescription() { return "Гуон-детектор (результат всегда одинаковый)"; }
@Override public String getUsage() { return "goon [@user]"; }
@Override public String getCategory() { return "Развлечения"; }
@Override
public void execute(CommandContext context) {
if (!ratingService.checkAndApplyCooldown(context, "goon")) return;
Member target = ratingService.resolveTarget(context);
if (target == null) return;
int level = ratingService.getDeterministicValue(target.getId(), 444, 0, 100);
StringBuilder bar = new StringBuilder();
int filled = level / 10;
for (int i = 0; i < filled; i++) bar.append("💀");
for (int i = filled; i < 10; i++) bar.append("⬜");
Color color = level >= 70 ? new Color(180, 0, 0) : level >= 40 ? new Color(128, 0, 128) : new Color(100, 100, 100);
context.getChannel().sendMessageEmbeds(
EmbedFactory.create().withTitle("💀 Goon-детектор").withDescription(target.getAsMention())
.addField("Уровень", bar + "\n**" + level + "%**", false)
.withThumbnail(target.getUser().getAvatarUrl()).withColor(color)
.withFooter("💡 Детерминировано вашим Discord ID").build()).queue();
}
}

View file

@ -0,0 +1,40 @@
package creator.loki.feature.rating.commands;
import com.google.inject.Inject;
import creator.loki.command.Command;
import creator.loki.command.CommandContext;
import creator.loki.embed.EmbedFactory;
import creator.loki.feature.entertainment.service.RatingService;
import creator.loki.feature.rating.config.RatingConfig;
import creator.loki.feature.rating.config.RatingLevel;
import net.dv8tion.jda.api.entities.Member;
public class SimpCommand implements Command {
private final RatingService ratingService;
@Inject
public SimpCommand(RatingService ratingService) { this.ratingService = ratingService; }
@Override public String getName() { return "simp"; }
@Override public String getDescription() { return "Симп-детектор (результат всегда одинаковый)"; }
@Override public String getUsage() { return "simp [@user]"; }
@Override public String getCategory() { return "Развлечения"; }
@Override
public void execute(CommandContext context) {
if (!ratingService.checkAndApplyCooldown(context, "simp")) return;
Member target = ratingService.resolveTarget(context);
if (target == null) return;
int level = ratingService.getDeterministicValue(target.getId(), 111, 0, 100);
StringBuilder bar = new StringBuilder();
int filled = level / 10;
for (int i = 0; i < filled; i++) bar.append("💀");
for (int i = filled; i < 10; i++) bar.append("⬜");
RatingLevel rl = RatingLevel.findLevel(level, RatingConfig.getSimpLevels());
context.getChannel().sendMessageEmbeds(
EmbedFactory.create().withTitle("😭 Симп-детектор").withDescription(target.getAsMention())
.addField("Уровень", bar + "\n**" + level + "%** - " + rl.getComment(), false)
.withThumbnail(target.getUser().getAvatarUrl()).withColor(rl.getColor())
.withFooter("💡 Детерминировано вашим Discord ID").build()).queue();
}
}

View file

@ -0,0 +1,40 @@
package creator.loki.feature.rating.commands;
import com.google.inject.Inject;
import creator.loki.command.Command;
import creator.loki.command.CommandContext;
import creator.loki.embed.EmbedFactory;
import creator.loki.feature.entertainment.service.RatingService;
import creator.loki.feature.rating.config.RatingConfig;
import creator.loki.feature.rating.config.RatingLevel;
import net.dv8tion.jda.api.entities.Member;
public class VibeCommand implements Command {
private final RatingService ratingService;
@Inject
public VibeCommand(RatingService ratingService) { this.ratingService = ratingService; }
@Override public String getName() { return "vibe"; }
@Override public String getDescription() { return "Проверить свой вайб (результат всегда одинаковый)"; }
@Override public String getUsage() { return "vibe [@user]"; }
@Override public String getCategory() { return "Развлечения"; }
@Override
public void execute(CommandContext context) {
if (!ratingService.checkAndApplyCooldown(context, "vibe")) return;
Member target = ratingService.resolveTarget(context);
if (target == null) return;
int level = ratingService.getDeterministicValue(target.getId(), 222, 0, 100);
StringBuilder bar = new StringBuilder();
int filled = level / 10;
for (int i = 0; i < filled; i++) bar.append("🎵");
for (int i = filled; i < 10; i++) bar.append("⬜");
RatingLevel rl = RatingLevel.findLevel(level, RatingConfig.getVibeLevels());
context.getChannel().sendMessageEmbeds(
EmbedFactory.create().withTitle("🎵 Вайб-чек").withDescription(target.getAsMention())
.addField("Вайб", bar + "\n**" + level + "%** - " + rl.getComment(), false)
.withThumbnail(target.getUser().getAvatarUrl()).withColor(rl.getColor())
.withFooter("💡 Детерминировано вашим Discord ID").build()).queue();
}
}

View file

@ -74,6 +74,27 @@ public class RatingConfig {
new RatingLevel(30, "😐 Ни туда ни сюда", new Color(128, 128, 128)),
new RatingLevel(10, "😬 Невезучий", new Color(255, 165, 0)),
new RatingLevel(0, "💀 Проклят", new Color(231, 76, 60))));
m.put("simp", List.of(
new RatingLevel(90, "👑 КОРОЛЬ СИМПОВ!", new Color(255, 105, 180)),
new RatingLevel(70, "😍 Задрот", new Color(255, 182, 193)),
new RatingLevel(50, "🙂 Нормальный", new Color(52, 152, 219)),
new RatingLevel(30, "😐 Холодный", new Color(128, 128, 128)),
new RatingLevel(10, "💪 Альфа", new Color(100, 255, 150)),
new RatingLevel(0, "🦍 ГОРИЛЛА", new Color(150, 100, 50))));
m.put("vibe", List.of(
new RatingLevel(90, "🎶 ЛЕГЕНДАРНЫЙ ВАЙБ!", new Color(255, 215, 0)),
new RatingLevel(70, "🔥 Крутой вайб", new Color(255, 100, 0)),
new RatingLevel(50, "🙂 Норм вайб", new Color(52, 152, 219)),
new RatingLevel(30, "😐 Так себе", new Color(128, 128, 128)),
new RatingLevel(10, "📉 Вайб упал", new Color(255, 165, 0)),
new RatingLevel(0, "💀 Вайба нет", new Color(231, 76, 60))));
m.put("glaze", List.of(
new RatingLevel(90, "🍩 НЕВЕРОЯТНО ГЛАЗИРОВАН!", new Color(255, 215, 0)),
new RatingLevel(70, "✨ Сияет", new Color(255, 200, 100)),
new RatingLevel(50, "🙂 Средне", new Color(52, 152, 219)),
new RatingLevel(30, "😐 Матовый", new Color(128, 128, 128)),
new RatingLevel(10, "🧊 Подтаивает", new Color(200, 200, 255)),
new RatingLevel(0, "💀 Сухой", new Color(150, 150, 150))));
LEVELS = Collections.unmodifiableMap(m);
}
@ -101,7 +122,8 @@ public class RatingConfig {
return LEVELS.get("rizz");
}
public static List<RatingLevel> getLuckLevels() {
return LEVELS.get("luck");
}
public static List<RatingLevel> getLuckLevels() { return LEVELS.get("luck"); }
public static List<RatingLevel> getSimpLevels() { return LEVELS.get("simp"); }
public static List<RatingLevel> getVibeLevels() { return LEVELS.get("vibe"); }
public static List<RatingLevel> getGlazeLevels() { return LEVELS.get("glaze"); }
}

View file

@ -0,0 +1,39 @@
package creator.loki.feature.utility;
import creator.loki.command.Command;
import creator.loki.command.CommandContext;
import creator.loki.embed.EmbedTemplates;
public class TimerCommand implements Command {
@Override public String getName() { return "timer"; }
@Override public String getDescription() { return "Запустить таймер"; }
@Override public String getUsage() { return "timer <секунд> [текст]"; }
@Override public String getCategory() { return "Утилиты"; }
@Override
public void execute(CommandContext ctx) {
if (ctx.getArgs().isEmpty()) {
ctx.getChannel().sendMessageEmbeds(EmbedTemplates.error("Таймер", "Укажи секунды: `!timer 30`")).queue();
return;
}
long secs;
try { secs = Long.parseLong(ctx.getArgs().get(0)); }
catch (NumberFormatException e) {
ctx.getChannel().sendMessageEmbeds(EmbedTemplates.error("Таймер", "Укажи число секунд")).queue();
return;
}
if (secs < 1 || secs > 3600) {
ctx.getChannel().sendMessageEmbeds(EmbedTemplates.error("Таймер", "От 1 до 3600 секунд")).queue();
return;
}
String msg = ctx.getArgs().size() > 1 ? String.join(" ", ctx.getArgs().subList(1, ctx.getArgs().size())) : "⏰ Таймер сработал!";
long targetEpoch = System.currentTimeMillis() / 1000 + secs;
ctx.getChannel().sendMessageEmbeds(EmbedTemplates.info("⏳ Таймер запущен",
"**" + secs + "**с (<t:" + targetEpoch + ":R>)\n" + ctx.getAuthor().getAsMention())).queue();
Thread.startVirtualThread(() -> {
try { Thread.sleep(secs * 1000); }
catch (InterruptedException e) { return; }
ctx.getChannel().sendMessage(msg + " " + ctx.getAuthor().getAsMention()).queue();
});
}
}

View file

@ -24,6 +24,7 @@ import creator.loki.feature.reputation.RepTopCommand;
import creator.loki.feature.reputation.repository.ReputationRepository;
import creator.loki.feature.serverstats.ServerStatsService;
import creator.loki.feature.utility.commands.PollCommand;
import creator.loki.feature.utility.TimerCommand;
import creator.loki.feature.voice.service.VoiceChannelManager;
import creator.loki.feature.voice.service.VoiceSetupPrefixCommand;
@ -72,6 +73,7 @@ public class UtilityCommandRegistrar implements CommandRegistrar {
registry.register(new AvatarCommand());
registry.register(new ServerStatsCommand(serverStatsService));
registry.register(new PollCommand());
registry.register(new TimerCommand());
registry.register(new VoiceSetupPrefixCommand(voiceChannelManager, configRepository));
registry.register(new CounterSetupPrefixCommand(counterManager, configRepository));