Compare commits
No commits in common. "stable" and "0.2.0" have entirely different histories.
|
@ -5,8 +5,7 @@ declare(strict_types=1);
|
||||||
namespace mirzaev\marina\controllers;
|
namespace mirzaev\marina\controllers;
|
||||||
|
|
||||||
// Файлы проекта
|
// Файлы проекта
|
||||||
use mirzaev\marina\controllers\core,
|
use mirzaev\marina\controllers\core;
|
||||||
mirzaev\marina\controllers\traits\converters;
|
|
||||||
|
|
||||||
// Discord framework
|
// Discord framework
|
||||||
use Discord\Discord as discord,
|
use Discord\Discord as discord,
|
||||||
|
@ -14,7 +13,6 @@ use Discord\Discord as discord,
|
||||||
Discord\Parts\Guild\Role as role,
|
Discord\Parts\Guild\Role as role,
|
||||||
Discord\Parts\Guild\CommandPermissions as permissions,
|
Discord\Parts\Guild\CommandPermissions as permissions,
|
||||||
Discord\Parts\User\Member as member,
|
Discord\Parts\User\Member as member,
|
||||||
Discord\Parts\Guild\ScheduledEvent as schedule,
|
|
||||||
Discord\Parts\Interactions\Interaction as interaction,
|
Discord\Parts\Interactions\Interaction as interaction,
|
||||||
Discord\WebSockets\Event as event,
|
Discord\WebSockets\Event as event,
|
||||||
Discord\Parts\Interactions\Command\Command as command,
|
Discord\Parts\Interactions\Command\Command as command,
|
||||||
|
@ -23,9 +21,7 @@ use Discord\Discord as discord,
|
||||||
Discord\Parts\Interactions\Command\Option as option;
|
Discord\Parts\Interactions\Command\Option as option;
|
||||||
|
|
||||||
// Встроенные библиотеки
|
// Встроенные библиотеки
|
||||||
use exception,
|
use exception;
|
||||||
datetime,
|
|
||||||
datetimezone;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Контроллер головного управления
|
* Контроллер головного управления
|
||||||
|
@ -35,10 +31,6 @@ use exception,
|
||||||
*/
|
*/
|
||||||
final class index extends core
|
final class index extends core
|
||||||
{
|
{
|
||||||
use converters {
|
|
||||||
utf8_to_extended_ascii as protected ascii;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Главная страница
|
* Главная страница
|
||||||
*
|
*
|
||||||
|
@ -52,7 +44,7 @@ final class index extends core
|
||||||
// Запись в буфер вывода (терминал)
|
// Запись в буфер вывода (терминал)
|
||||||
echo "Marina is ready!", PHP_EOL;
|
echo "Marina is ready!", PHP_EOL;
|
||||||
|
|
||||||
// Сообщение: создано
|
// Сообщение: "марина"
|
||||||
$discord->on(event::MESSAGE_CREATE, function (message $message, discord $discord) {
|
$discord->on(event::MESSAGE_CREATE, function (message $message, discord $discord) {
|
||||||
// Игнорирование чат-роботов
|
// Игнорирование чат-роботов
|
||||||
if ($message->author->bot) return;
|
if ($message->author->bot) return;
|
||||||
|
@ -60,99 +52,12 @@ final class index extends core
|
||||||
// Запись в буфер вывода (терминал)
|
// Запись в буфер вывода (терминал)
|
||||||
echo "{$message->author->username}: {$message->content}", PHP_EOL;
|
echo "{$message->author->username}: {$message->content}", PHP_EOL;
|
||||||
|
|
||||||
if ($message->author->id === '490821645028687873' || mb_stristr($message->content, 'мимк') !== false) {
|
if (mb_stristr($message->content, 'марина') !== false) {
|
||||||
// Сообщение от Дмитрия Демина (мимк) (vladimirbaryshkin) или содержит его псевдоним
|
$message->reply(_message::new()->setContent('ЗДАРОВА'));
|
||||||
|
|
||||||
// Добавление реакции на его сообщение
|
|
||||||
$message->react('😬');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($message->author->id === '380876873468608522' && rand(0, 100) < 2) {
|
|
||||||
// Сообщение от Даниила Богданова (godandem) и шанс 1%
|
|
||||||
|
|
||||||
// Отправка изображения: "надругался над даниилом богдановым"
|
|
||||||
$message->channel->sendMessage(_message::new()->addFile('images/daniil.png'));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (explode(' ', $message->content) as $word) {
|
|
||||||
// Перебор слов из текста сообщения
|
|
||||||
|
|
||||||
// Инициализация буфера символов для конвертации: UTF-8 -> ASCII+
|
|
||||||
$buffer = [];
|
|
||||||
|
|
||||||
// Конвертация проверяемых слов
|
|
||||||
$arsen = self::ascii('арсен', $buffer);
|
|
||||||
$arsenchik = self::ascii('арсенчик', $buffer);
|
|
||||||
$senya = self::ascii('сеня', $buffer);
|
|
||||||
|
|
||||||
// Конвертация слова
|
|
||||||
$_word = self::ascii(mb_strtolower($word), $buffer);
|
|
||||||
|
|
||||||
if (
|
|
||||||
($mirzaev = $message->guild->members->get('id', '534633964737134623')) instanceof member
|
|
||||||
&& ($mirzaev->status === 'offline' || $mirzaev->status === null)
|
|
||||||
&& rand(0, 100) < 26
|
|
||||||
and levenshtein($_word, $arsen, 2, 2, 1) < 3
|
|
||||||
|| levenshtein($_word, $arsenchik, 2, 1, 2) < 4
|
|
||||||
|| (levenshtein($_word, $senya, 2, 2, 1) < 2 && $word !== 'меня' && $word !== 'тебя')
|
|
||||||
) {
|
|
||||||
// Найдено обращение к Арсену, он не в сети и шанс 25%
|
|
||||||
|
|
||||||
// Отправка сообщения
|
|
||||||
$message->reply(_message::new()->setContent(match (rand(0, 5)) {
|
|
||||||
0 => 'батя спит',
|
|
||||||
1 => 'арсен проломил себе голову и находится в реанимации',
|
|
||||||
2 => '"МАРИНА ПЕРЕДАЙ ИМ ЧТО Я В БЕГАХ В ТАДЖИКИСТАНЕ"',
|
|
||||||
3 => 'ему раздавили яйца и он лежит в соседней комнате без сознания',
|
|
||||||
4 => 'папа меня бьёт за то, что я не удаляю такие сообщения :sob:',
|
|
||||||
5 => '<:smart:1105401468019822643>',
|
|
||||||
default => '<:smart:1105401468019822643>'
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
// Не найдено обращение к Арсену
|
|
||||||
|
|
||||||
// Инициализация буфера символов для конвертации: UTF-8 -> ASCII+
|
|
||||||
$buffer = [];
|
|
||||||
|
|
||||||
// Конвертация проверяемых слов
|
|
||||||
$marina = self::ascii('марина', $buffer);
|
|
||||||
$marishka = self::ascii('маришка', $buffer);
|
|
||||||
$marinochka = self::ascii('мариночка', $buffer);
|
|
||||||
$marinushka = self::ascii('маринушка', $buffer);
|
|
||||||
$marya = self::ascii('маря', $buffer);
|
|
||||||
|
|
||||||
// Конвертация слова
|
|
||||||
$_word = self::ascii(mb_strtolower($word), $buffer);
|
|
||||||
|
|
||||||
if (
|
|
||||||
rand(0, 100) < 31
|
|
||||||
and
|
|
||||||
match ($word) {
|
|
||||||
'машинка', 'мария', 'малинка', 'машина', 'малина' => false,
|
|
||||||
default => true
|
|
||||||
}
|
|
||||||
&& (levenshtein($_word, $marina, 2, 2, 1) < 3)
|
|
||||||
|| levenshtein($_word, $marishka, 2, 1, 2) < 4
|
|
||||||
|| levenshtein($_word, $marinochka, 2, 1, 2) < 4
|
|
||||||
|| levenshtein($_word, $marinushka, 2, 1, 2) < 4
|
|
||||||
|| (levenshtein($_word, $marya, 3, 3, 1) < 3)
|
|
||||||
) {
|
|
||||||
// Найдено обращение к Марине и шанс 30%
|
|
||||||
|
|
||||||
// Отправка сообщения
|
|
||||||
$message->reply(_message::new()->setContent(rand(0, 100) < 10 ? '🥺' : 'ЗДАРОВА'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Деинициализация неактуальных переменных
|
|
||||||
unset($buffer, $marina, $marishka, $marinochka, $marya, $_word);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Деинициализация неактуальных переменных
|
|
||||||
unset($buffer, $arsen, $arsenchik, $senya, $_word);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Пользователь: обновление
|
// Пользователь: обновление роли
|
||||||
$discord->on(event::GUILD_MEMBER_UPDATE, function (member $new, discord $discord, ?member $old = null) {
|
$discord->on(event::GUILD_MEMBER_UPDATE, function (member $new, discord $discord, ?member $old = null) {
|
||||||
// Запись в буфер вывода (терминал)
|
// Запись в буфер вывода (терминал)
|
||||||
|
|
||||||
|
@ -295,166 +200,13 @@ final class index extends core
|
||||||
*/
|
*/
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach ($discord->guilds as $guild) {
|
|
||||||
// Перебор серверов
|
|
||||||
|
|
||||||
if (!($guild->guild_scheduled_events->get('name', 'Saturdaynik 🧹') instanceof schedule)) {
|
|
||||||
// Не найдено событие: "субботник"
|
|
||||||
|
|
||||||
// Инициализация даты субботника
|
|
||||||
$date = new datetime('next saturday', new datetimezone('UTC'));
|
|
||||||
|
|
||||||
if ($trash = $guild->channels->get('name', 'trash')) {
|
|
||||||
// Найден канал: "trash"
|
|
||||||
|
|
||||||
if ($saturdaynik = $trash->threads->get('name', 'Saturdaynik 🧹')) {
|
|
||||||
// Найден канал для субботников
|
|
||||||
|
|
||||||
$saturdaynik->sendMessage("Next saturdaynik starts on <t:{$date->format('U')}:D>")
|
|
||||||
->then(function ($message) use ($discord, $date, $guild, $saturdaynik) {
|
|
||||||
// Закрепление сообщения
|
|
||||||
$saturdaynik->pinMessage($message, 'Notification about the next saturdaynik')
|
|
||||||
->then(function ($message) use ($saturdaynik) {
|
|
||||||
$saturdaynik->getMessageHistory(['limit' => 1])->then(function ($messages) {
|
|
||||||
|
|
||||||
// Удаление сообщения о том, что Марина закрепила сообщение
|
|
||||||
$messages->first()->delete();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Создание события
|
|
||||||
$guild->guild_scheduled_events->save(
|
|
||||||
new schedule($discord, [
|
|
||||||
'name' => 'Saturdaynik 🧹',
|
|
||||||
'description' => "Global saturday cleaning on our server - saturdaynik!\nYour keyboards will be shine! 😼✨",
|
|
||||||
'scheduled_start_time' => $date->format(datetime::ATOM),
|
|
||||||
'scheduled_end_time' => (clone $date)->modify('+1 day')->format(datetime::ATOM),
|
|
||||||
'image' => \Discord\imageToBase64('images/saturdaynik/cover.jpg'),
|
|
||||||
'entity_type' => 3,
|
|
||||||
'entity_metadata' => [
|
|
||||||
'location' => $message->getLinkAttribute()
|
|
||||||
],
|
|
||||||
'privacy_level' => 2
|
|
||||||
])
|
|
||||||
)->then(function ($event) use ($guild) {
|
|
||||||
if ($events = $guild->channels->get('name', 'events')) {
|
|
||||||
// Найден канал: "events
|
|
||||||
|
|
||||||
// Инициализация буфера идентификатора роли для оповещения о событиях
|
|
||||||
$id = '';
|
|
||||||
|
|
||||||
foreach ($guild->roles as $role) {
|
|
||||||
// Чтение ролей
|
|
||||||
|
|
||||||
if ($role->name === "Events") {
|
|
||||||
// Найдена роль для оповещения о событиях
|
|
||||||
|
|
||||||
// Запись идентификатора роли
|
|
||||||
$id = $role->id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Отправка сообщения с приглашением присоединиться к субботнику
|
|
||||||
$events->sendMessage((empty($id) ? '' : "<@&{$id}> ") . "https://discord.gg/pMZaxvH4?event={$event->id}");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Не найден канал для субботников (подразумевается)
|
|
||||||
|
|
||||||
// Создание канала (ветки) для субботников
|
|
||||||
$trash->startThread([
|
|
||||||
'name' => 'Saturdaynik 🧹'
|
|
||||||
], 'Thread for saturdaynik')
|
|
||||||
->then(function ($thread) use ($discord, $date, $guild, $trash) {
|
|
||||||
// Отправка первого сообщения в ветке с полной версией обложки
|
|
||||||
$thread->sendMessage(
|
|
||||||
_message::new()
|
|
||||||
->addFile('images/saturdaynik/source.jpg')
|
|
||||||
)
|
|
||||||
->then(function ($message) use ($discord, $date, $guild, $trash) {
|
|
||||||
if ($saturdaynik = $trash->threads->get('name', 'Saturdaynik 🧹')) {
|
|
||||||
// Найден канал для субботников
|
|
||||||
|
|
||||||
$saturdaynik->sendMessage("Next saturdaynik starts on <t:{$date->format('U')}:D>")
|
|
||||||
->then(function ($message) use ($discord, $date, $guild, $saturdaynik) {
|
|
||||||
// Закрепление сообщения
|
|
||||||
$saturdaynik->pinMessage($message, 'Notification about the next saturdaynik')
|
|
||||||
->then(function ($message) use ($saturdaynik) {
|
|
||||||
$saturdaynik->getMessageHistory(['limit' => 1])->then(function ($messages) {
|
|
||||||
|
|
||||||
// Удаление сообщения о том, что Марина закрепила сообщение
|
|
||||||
$messages->first()->delete();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Создание события
|
|
||||||
$guild->guild_scheduled_events->save(
|
|
||||||
new schedule($discord, [
|
|
||||||
'name' => 'Saturdaynik 🧹',
|
|
||||||
'description' => "Global saturday cleaning - saturdaynik!\nYour keyboards will be shine! 😼✨",
|
|
||||||
'scheduled_start_time' => $date->format(datetime::ATOM),
|
|
||||||
'scheduled_end_time' => (clone $date)->modify('+1 day')->format(datetime::ATOM),
|
|
||||||
'image' => \Discord\imageToBase64('images/saturdaynik/cover.jpg'),
|
|
||||||
'entity_type' => 3,
|
|
||||||
'entity_metadata' => [
|
|
||||||
'location' => $message->getLinkAttribute()
|
|
||||||
],
|
|
||||||
'privacy_level' => 2
|
|
||||||
])
|
|
||||||
)->then(function ($event) use ($guild) {
|
|
||||||
if ($events = $guild->channels->get('name', 'events')) {
|
|
||||||
// Найден канал: "events
|
|
||||||
|
|
||||||
// Инициализация буфера идентификатора роли для оповещения о событиях
|
|
||||||
$id = '';
|
|
||||||
|
|
||||||
foreach ($guild->roles as $role) {
|
|
||||||
// Чтение ролей
|
|
||||||
|
|
||||||
if ($role->name === "Events") {
|
|
||||||
// Найдена роль для оповещения о событиях
|
|
||||||
|
|
||||||
// Запись идентификатора роли
|
|
||||||
$id = $role->id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Отправка сообщения с приглашением присоединиться к субботнику
|
|
||||||
$events->sendMessage((empty($id) ? '' : "<@&{$id}> ") . "https://discord.gg/pMZaxvH4?event={$event->id}");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Не найден канал для субботников (подразумевается)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$discord->on(event::GUILD_SCHEDULED_EVENT_CREATE, function (schedule $schedule, Discord $discord) {
|
|
||||||
/* var_dump($schedule); */
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
$discord->application->commands->save(new command($discord, [
|
$discord->application->commands->save(new command($discord, [
|
||||||
'name' => 'dreamers',
|
'name' => 'dreamers',
|
||||||
'description' => 'BEBRA DREAMERS',
|
'description' => 'BEBRA DREAMERS',
|
||||||
'options' => [
|
'options' => [(new option($discord))
|
||||||
(new option($discord))
|
->setName('invite')
|
||||||
->setName('invite')
|
->setDescription('Send an invitation link to "BEBRA DREAMERS"')
|
||||||
->setDescription('Link to "BEBRA DREAMERS"')
|
->setType(option::SUB_COMMAND)]
|
||||||
->setType(option::SUB_COMMAND),
|
|
||||||
(new option($discord))
|
|
||||||
->setName('rules')
|
|
||||||
->setDescription('Rules of "BEBRA DREAMERS"')
|
|
||||||
->setType(option::SUB_COMMAND)
|
|
||||||
]
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
$discord->listenCommand(['dreamers', 'invite'], function (interaction $interaction) {
|
$discord->listenCommand(['dreamers', 'invite'], function (interaction $interaction) {
|
||||||
|
@ -464,14 +216,6 @@ final class index extends core
|
||||||
// Отправка ссылки с приглашением присоединиться на сервер BEBRA DREAMERS
|
// Отправка ссылки с приглашением присоединиться на сервер BEBRA DREAMERS
|
||||||
if ($interaction->data->options->has('invite')) $interaction->respondWithMessage(_message::new()->setContent('https://discord.bebra.team'));
|
if ($interaction->data->options->has('invite')) $interaction->respondWithMessage(_message::new()->setContent('https://discord.bebra.team'));
|
||||||
});
|
});
|
||||||
|
|
||||||
$discord->listenCommand(['dreamers', 'rules'], function (interaction $interaction) {
|
|
||||||
// Игнорирование чат-роботов
|
|
||||||
if ($interaction->user->bot) return;
|
|
||||||
|
|
||||||
// Отправка ссылки с приглашением присоединиться на сервер BEBRA DREAMERS
|
|
||||||
if ($interaction->data->options->has('rules')) $interaction->respondWithMessage(_message::new()->setContent('https://rules.bebra.team'));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->discord->run();
|
$this->discord->run();
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace mirzaev\marina\controllers\traits;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Заготовки для конвертации строк
|
|
||||||
*
|
|
||||||
* @package mirzaev\marina\controllers\traits
|
|
||||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
|
||||||
*/
|
|
||||||
trait converters
|
|
||||||
{
|
|
||||||
private static function utf8_to_extended_ascii(string $target, &$map)
|
|
||||||
{
|
|
||||||
// find all multibyte characters (cf. utf-8 encoding specs)
|
|
||||||
$matches = array();
|
|
||||||
if (!preg_match_all('/[\xC0-\xF7][\x80-\xBF]+/', $target, $matches))
|
|
||||||
return $target; // plain ascii string
|
|
||||||
|
|
||||||
// update the encoding map with the characters not already met
|
|
||||||
foreach ($matches[0] as $mbc)
|
|
||||||
if (!isset($map[$mbc]))
|
|
||||||
$map[$mbc] = chr(128 + count($map));
|
|
||||||
|
|
||||||
// finally remap non-ascii characters
|
|
||||||
return strtr($target, $map);
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 390 KiB |
Binary file not shown.
Before Width: | Height: | Size: 162 KiB |
Binary file not shown.
Before Width: | Height: | Size: 316 KiB |
Loading…
Reference in New Issue