Files
mybb-april-fools/src/joker.ts
T

184 lines
4.3 KiB
TypeScript

import { Joke, JokeSettings } from "./joke";
/**
* Блок обработки перво-апрельских шуток
*
* @author Kozhilya
*/
export class JokerClass {
/**
* Проверка вероятности
*
* @param {number} chance Вероятность срабатывания
* @returns {boolean} Флаг срабатывания (true - сработало)
*/
check(chance: number): boolean {
return Math.random() < 0.01 * chance;
}
/**
* Добавление шутки
*
* @param joke Объект шутки
*/
add(joke: Joke): void {
this.jokes[joke.id] = joke;
}
/**
* Регистрация новой шутки
*
* @param id Идентификатор шутки
* @param handler Метод, выполняющий шутку
* @param settings Объект настроек шутки
*/
addCustom(id: string, handler: Function, settings: JokeSettings|null = null) {
const joke = new class extends Joke {
id = id;
settings: JokeSettings = { chance: 10, enabled: true };
start() {
handler.call(this, this.settings);
}
};
Object.assign(joke.settings, settings ?? {});
this.add(joke);
}
/**
* Получение полного списка настроек
*/
get settings(): SettingsMap {
const result: SettingsMap = {};
result['core'] = this.core_settings;
for (const entries of Object.entries(this.jokes)) {
const id = entries[0];
const joke = entries[1];
result[id] = joke.settings;
}
return result;
}
/**
* Запись новых настроек
*
* @param settings
*/
set settings(settings: SettingsMap) {
for (const entry of Object.entries(settings)) {
const id = entry[0];
const jokeSettings = entry[1];
const targetSettings = (id === 'core') ? this.core_settings : this.jokes[id].settings;
Object.assign(targetSettings, jokeSettings);
}
}
/**
* Разблокировать систему
*/
enable() {
this.core_settings.enabled = true;
}
/**
* Заблокировать систему
*/
disable() {
this.core_settings.enabled = false;
}
/**
* Разблокировать все шутки
*/
enableAll() {
for (const key of Object.keys(this.jokes)) {
this.jokes[key].enable();
}
}
/**
* Заблокировать все шутки
*/
disableAll() {
for (const key of Object.keys(this.jokes)) {
this.jokes[key].disable();
}
}
/**
* Запуск шутки
*
* @param id
* @param {boolean} forced
*/
start(id: string, forced: boolean = false) {
if (!(id in this.jokes))
return;
const joke = this.jokes[id];
if (!forced && (!joke.settings.enabled || !this.check(joke.settings.chance))) {
return;
}
joke.start();
}
/**
* Запуск всех шуток
*/
startAll(forced: boolean = false): void {
for (const key of Object.keys(this.jokes)) {
this.start(key, forced);
}
}
regularStart(): void {
const today = new Date();
const month = today.getMonth() + 1; // Note that getMonth() returns 0-indexed month, so we need to add 1
const day = today.getDate();
if (month !== 4 || day !== 1 || !this.core_settings.enabled || !this.check(this.core_settings.chance)) {
return;
}
this.startAll();
}
/**
* Общие настройки системы
*/
core_settings = new CoreSettings;
/**
* Перечисление всех шуток
*/
jokes: JokeMap = {}
}
/**
* Объект хранения шуток
*/
interface JokeMap {
[key: string]: Joke;
}
/**
* Объект задания настроек
*/
interface SettingsMap {
[key: string]: JokeSettings;
}
class CoreSettings implements JokeSettings {
chance = 100;
enabled = true;
}