Обработка команд для Discord Bot - PullRequest
0 голосов
/ 01 июля 2019

Я работаю над Discord Bot для модерации.Я использую библиотеку JDA.В настоящее время я застрял в обработке команд.

Существует 4 сценария команд:

".ban <@302390080104955904> advertising"
".ban <@!302390080104955904> advertising"
".ban 302390080104955904 advertising"
".ban et advertising"

Когда бот получает команду, я подстановка команды и префикса.

В первую очередьСценарий Я хочу извлечь идентификатор "302390080104955904" и удалить его из строки, поэтому я просто получаю причину

Второй сценарий такой же, как первый, но у него есть восклицательный знак после @

В третьемВ этом сценарии мне просто нужно извлечь идентификатор и удалить его

И в последнем сценарии мне нужно только указать имя пользователя и выполнить поиск пользователя.

Я пытался реализовать это несколько разно я всегда терпел неудачу.Любые идеи о том, как я могу сделать эту работу

РЕДАКТИРОВАТЬ: Я принимаю как Kotlin, так и Java ответы

1 Ответ

3 голосов
/ 01 июля 2019

Я предполагаю, что у вас уже есть метод для отделения команды от ее содержимого - если я неправильно понял эту часть, пожалуйста, исправьте меня.

Как только вы отделите саму команду от содержимого, вы получите строку, похожую на:

val commandContent = "<@!302390080104955904> advertising";

Отсюда вам нужно разделить его:

val cache = commandContent.split(" ", limit=2);

Теперь у вас есть массив размером до двух.

Оттуда, проанализируйте его немного дальше, чтобы сохранить ваши данные:

// Note: I haven't implemented any safety. If you get an unexpected size, you'll need to handle that yourself
val target = cache[0];
val reason = cache[1];

отсюда вы можете использовать регулярные выражения. Прежде чем я углублюсь в код, позвольте мне объяснить регулярное выражение:

<?        - Attempt to match an opening bracket
@?        - Attempt to find @
!?        - Attempt to find !
([0-9]+)  - Constant: find a group of numbers
>?        - Attempt to find a closing bracket

Это также помогает отфильтровывать имена пользователей в формате username#discriminator - любой нечисловой символ распознает строку как не идентификатор. Вы также можете поиграть с ним на regex101.com .

Здесь вы можете установить соответствие:

val regex = """<?@?!?([0-9]+)>?""".toRegex()
fun getMatch(target: String) : String? = regex.matchEntire(target)?.groups?.get(1)?.value

getMatch(target) возвращает ноль, если идентификатор не найден, и идентификатор в виде строки в противном случае.

Теперь все, что вам нужно сделать, это вызвать метод и делать все, что вы хотите:

val match = getMatch(target); 
if (match != null) {
    // You have the UID. 
} else {
    // You have a username. Use `target` to retrieve the user ID. 
} 

Хотя это работает, есть что-то, что вам нужно иметь в виду: когда речь идет об именах пользователей, в ваш пример входит только имя пользователя без дискриминатора. Если ваш бот подключается к достаточно большому серверу, и вы, например, перебираете пользователей, чтобы найти сервер с подходящим именем пользователя, вы, вероятно, обнаружите, что забанили не того человека или запретили всем с этим именем пользователя, если вы забыли прервать цикл.

На вашем месте я бы проверил наличие #[0-9]{4} либо с помощью регулярного выражения, либо разделив имя пользователя на # и убедившись, что вы получите две части, а вторая часть состоит только из цифр:

val split = target.split("#")
if (split.size != 2) // Fail
if (split[1].toLongOrNull() == null || split[1].length != 4 || split[1].contains("-")) // fail - non-number long, invalid discriminator (discriminators are always 4 digits), or negative discriminator 

Дискриминаторы находятся в диапазоне от 0001 до 9999. В любом случае, он всегда имеет 4 цифры. Обратите внимание, что преобразование в long теряет любые префиксы 0, поэтому придерживайтесь строк для проверки. И если вы запускаете эту проверку, вам нужно запустить ее для имени пользователя, , а не псевдонима (псевдонимы могут содержать #, имена пользователей не могут)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...