Compare commits

..

No commits in common. "stable" and "0.2.0" have entirely different histories.

5 changed files with 10 additions and 296 deletions

View File

@ -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('Link to "BEBRA DREAMERS"') ->setDescription('Send an invitation 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();

View File

@ -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